﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using QLabValues;
using ParserCore;
using AtomicTypes;



namespace NumericalCalculations
{
    public partial class Functions
    {
        //Dictionary koji sadrzi pozive
        public static Dictionary<Identifier, f> FunctionsDictionary;


        //metod za punjenje distionary-ja
        //kada se napravi instanca klase Functions, npr. f,
        //potrebno je da se pozove ovaj metod,
        // posle se fje pozivaju sa f.FunctionsDictionary["ime_funkcije"](Lista<IQlabValue> p)
        public void addFunctions()
        {
            FunctionsDictionary = new Dictionary<Identifier, f>();
            
            //aritmeticki operatori
            FunctionsDictionary.Add(new Identifier("+"), plus_op);
            FunctionsDictionary.Add(new Identifier("-"), minus_op);
                   
            FunctionsDictionary.Add(new Identifier(".*"), times);
            FunctionsDictionary.Add(new Identifier("./"), rdivide);
            FunctionsDictionary.Add(new Identifier(".\\"), ldivide);
            FunctionsDictionary.Add(new Identifier("'"), ctranspose);
            FunctionsDictionary.Add(new Identifier(".'"), transpose);
            FunctionsDictionary.Add(new Identifier("*"), mtimes);

            // DODAO NETKO ZA TESTIRANJE
            FunctionsDictionary.Add(new Identifier("/"), rdivide);

            //relacioni operatori
            FunctionsDictionary.Add(new Identifier(">="), ge);
            FunctionsDictionary.Add(new Identifier(">"), gt);
            FunctionsDictionary.Add(new Identifier("<="), le);
            FunctionsDictionary.Add(new Identifier("<"), lt);
            FunctionsDictionary.Add(new Identifier("=="), eq);
            FunctionsDictionary.Add(new Identifier("~="), ne);

            //logicki operatori
            FunctionsDictionary.Add(new Identifier("&"), and);
            FunctionsDictionary.Add(new Identifier("|"), or);
            FunctionsDictionary.Add(new Identifier("~"), not);

            //short-circuit logicki operatori
            FunctionsDictionary.Add(new Identifier("&&"), shcircand);
            FunctionsDictionary.Add(new Identifier("||"), shcircor);

                        

            //funkcije
            FunctionsDictionary.Add(new Identifier("plus"), plus);
            FunctionsDictionary.Add(new Identifier("minus"), minus);
            FunctionsDictionary.Add(new Identifier("uplus"), uplus);
            FunctionsDictionary.Add(new Identifier("uminus"), uminus);
            FunctionsDictionary.Add(new Identifier("times"), times);
            FunctionsDictionary.Add(new Identifier("rdivide"), rdivide);
            FunctionsDictionary.Add(new Identifier("ldivide"), ldivide);
            FunctionsDictionary.Add(new Identifier("ctranspose"), ctranspose);
            FunctionsDictionary.Add(new Identifier("transpose"), transpose);
            FunctionsDictionary.Add(new Identifier("mtimes"), mtimes);

            FunctionsDictionary.Add(new Identifier("ge"), ge);
            FunctionsDictionary.Add(new Identifier("gt"), gt);
            FunctionsDictionary.Add(new Identifier("le"), le);
            FunctionsDictionary.Add(new Identifier("lt"), lt);
            FunctionsDictionary.Add(new Identifier("eq"), eq);
            FunctionsDictionary.Add(new Identifier("ne"), ne);

            FunctionsDictionary.Add(new Identifier("and"), and);
            FunctionsDictionary.Add(new Identifier("or"), or);
            FunctionsDictionary.Add(new Identifier("not"), not);
            FunctionsDictionary.Add(new Identifier("xor"), xor);

            //druge fje
            FunctionsDictionary.Add(new Identifier("abs"), abs);

            FunctionsDictionary.Add(new Identifier("acos"), acos);
            FunctionsDictionary.Add(new Identifier("asin"), asin);
            FunctionsDictionary.Add(new Identifier("atan"), atan);

            FunctionsDictionary.Add(new Identifier("acosh"), acosh);
            FunctionsDictionary.Add(new Identifier("asinh"), asinh);
            FunctionsDictionary.Add(new Identifier("atanh"), atanh);

            FunctionsDictionary.Add(new Identifier("cos"), cos);
            FunctionsDictionary.Add(new Identifier("sin"), sin);
            FunctionsDictionary.Add(new Identifier("tan"), tan);

            FunctionsDictionary.Add(new Identifier("cosh"), cosh);
            FunctionsDictionary.Add(new Identifier("sinh"), sinh);
            FunctionsDictionary.Add(new Identifier("tanh"), tanh);

            FunctionsDictionary.Add(new Identifier("bitmax"), bitmax);
            FunctionsDictionary.Add(new Identifier("bitcmp"), bitcmp);
            FunctionsDictionary.Add(new Identifier("bitget"), bitget);
            FunctionsDictionary.Add(new Identifier("bitset"), bitset);
            FunctionsDictionary.Add(new Identifier("bitshift"), bitshift);
            FunctionsDictionary.Add(new Identifier("bitand"), bitand);
            FunctionsDictionary.Add(new Identifier("bitor"), bitor);
            FunctionsDictionary.Add(new Identifier("bitxor"),  bitxor);

            FunctionsDictionary.Add(new Identifier("ceil"), ceil);
            FunctionsDictionary.Add(new Identifier("floor"), floor);
            FunctionsDictionary.Add(new Identifier("round"), round);
            FunctionsDictionary.Add(new Identifier("fix"), fix);

            FunctionsDictionary.Add(new Identifier("complex"), complex);
            FunctionsDictionary.Add(new Identifier("conj"), conj);
            FunctionsDictionary.Add(new Identifier("real"), real);
            FunctionsDictionary.Add(new Identifier("imag"), imag);

            FunctionsDictionary.Add(new Identifier("exp"), exp);
            FunctionsDictionary.Add(new Identifier("log"), log);
            FunctionsDictionary.Add(new Identifier("log2"), log2);

            FunctionsDictionary.Add(new Identifier("ischar"), ischar);
            FunctionsDictionary.Add(new Identifier("isempty"), isempty);
            FunctionsDictionary.Add(new Identifier("isfinite"), isfinite);
            FunctionsDictionary.Add(new Identifier("isnan"), isnan);
            FunctionsDictionary.Add(new Identifier("isinf"), isinf);
            FunctionsDictionary.Add(new Identifier("isfloat"), isfloat);
            FunctionsDictionary.Add(new Identifier("isinteger"), isinteger);
            FunctionsDictionary.Add(new Identifier("isletter"), isletter);
            FunctionsDictionary.Add(new Identifier("isnumeric"), isnumeric);
            FunctionsDictionary.Add(new Identifier("isreal"), isreal);
            FunctionsDictionary.Add(new Identifier("isscalar"), isscalar);
            FunctionsDictionary.Add(new Identifier("isspace"), isspace);
            FunctionsDictionary.Add(new Identifier("isvector"), isvector);
            FunctionsDictionary.Add(new Identifier("iscell"), iscell);
            FunctionsDictionary.Add(new Identifier("isstruct"), isstruct);
            FunctionsDictionary.Add(new Identifier("isvarname"), isvarname);
            FunctionsDictionary.Add(new Identifier("isa"), isa);

            FunctionsDictionary.Add(new Identifier("mod"), mod);
            FunctionsDictionary.Add(new Identifier("ndims"), ndims);
            FunctionsDictionary.Add(new Identifier("nnz"), nnz);

            FunctionsDictionary.Add(new Identifier("pow2"), pow2);
            FunctionsDictionary.Add(new Identifier("power"), power);
            FunctionsDictionary.Add(new Identifier("reallog"), reallog);
            FunctionsDictionary.Add(new Identifier("realpow"), realpow);
            FunctionsDictionary.Add(new Identifier("realsqrt"), realsqrt);
            FunctionsDictionary.Add(new Identifier("rem"), rem);
            FunctionsDictionary.Add(new Identifier("sign"), sign);
            FunctionsDictionary.Add(new Identifier("sqrt"), sqrt);

            FunctionsDictionary.Add(new Identifier("isstr"), isstr);
            FunctionsDictionary.Add(new Identifier("deblank"), deblank);
            FunctionsDictionary.Add(new Identifier("findstr"), findstr);
            FunctionsDictionary.Add(new Identifier("lower"), lower);
            FunctionsDictionary.Add(new Identifier("uper"), uper);
            FunctionsDictionary.Add(new Identifier("strrep"), strrep);
            FunctionsDictionary.Add(new Identifier("strcmp"), strcmp);
            FunctionsDictionary.Add(new Identifier("strcmpi"), strcmpi);
            FunctionsDictionary.Add(new Identifier("atan2"), atan2);
            FunctionsDictionary.Add(new Identifier("hypot"), hypot);
            FunctionsDictionary.Add(new Identifier("false"), ffalse);
            FunctionsDictionary.Add(new Identifier("true"), ttrue);
            FunctionsDictionary.Add(new Identifier("zeros"), zeros);
            FunctionsDictionary.Add(new Identifier("ones"), ones);
            FunctionsDictionary.Add(new Identifier("eye"), eye);

            FunctionsDictionary.Add(new Identifier("isequal"), isequal);
            FunctionsDictionary.Add(new Identifier("isequalwithequalnans"), isequalwithequalnans);
            FunctionsDictionary.Add(new Identifier("issorted"), issorted);
            FunctionsDictionary.Add(new Identifier("cumsum"), cumsum);
            FunctionsDictionary.Add(new Identifier("cumprod"), cumprod);
            FunctionsDictionary.Add(new Identifier("all"), all);
            FunctionsDictionary.Add(new Identifier("any"), any);
            FunctionsDictionary.Add(new Identifier("size"), size);
            FunctionsDictionary.Add(new Identifier("sort"), sort);
            FunctionsDictionary.Add(new Identifier("permute"), permute);
            FunctionsDictionary.Add(new Identifier("find"), find);
            FunctionsDictionary.Add(new Identifier("reshape"), reshape);
            FunctionsDictionary.Add(new Identifier("filter"), filter);
            FunctionsDictionary.Add(new Identifier("colon"), colon);
            

            FunctionsDictionary.Add(new Identifier("Inf"), inf);
            FunctionsDictionary.Add(new Identifier("NaN"), nan);
            FunctionsDictionary.Add(new Identifier("namelengthmax"), namelengthmax);

            FunctionsDictionary.Add(new Identifier("regexp"), regexp);
            FunctionsDictionary.Add(new Identifier("regexpi"), regexpi);

            //treba im provera i unit testovi
            FunctionsDictionary.Add(new Identifier("logical"), logical);
            FunctionsDictionary.Add(new Identifier("char"), cchar);
            FunctionsDictionary.Add(new Identifier("int64"), int64);
            FunctionsDictionary.Add(new Identifier("uint64"), uint64);
            FunctionsDictionary.Add(new Identifier("double"), ddouble);

            //nakrpljene
            FunctionsDictionary.Add(new Identifier("min"), min);
            FunctionsDictionary.Add(new Identifier("max"), max);
            FunctionsDictionary.Add(new Identifier("sum"), sum);
            FunctionsDictionary.Add(new Identifier("prod"), prod);
            //FunctionsDictionary.Add(new Identifier("size"), size);
            // Added by AM
            FunctionsDictionary.Add(new Identifier("length"), length);
            FunctionsDictionary.Add(new Identifier("strncmp"), strncmp);
            FunctionsDictionary.Add(new Identifier("triu"), triu);
            FunctionsDictionary.Add(new Identifier("tril"), tril);
            FunctionsDictionary.Add(new Identifier("diag"), diag);
            FunctionsDictionary.Add(new Identifier("numel"), numel);
            FunctionsDictionary.Add(new Identifier("nzmax"), nzmax);
            FunctionsDictionary.Add(new Identifier("nonzeros"), nonzeros);
            FunctionsDictionary.Add(new Identifier("isstrprop"), isstrprop);
            FunctionsDictionary.Add(new Identifier("rand"), rand);
            FunctionsDictionary.Add(new Identifier("randi"), randi);
            FunctionsDictionary.Add(new Identifier("randn"), randn);
            FunctionsDictionary.Add(new Identifier("strncmpi"), strncmpi);
            FunctionsDictionary.Add(new Identifier("setenv"), setenv);
            FunctionsDictionary.Add(new Identifier("getenv"), getenv);

            //Plotting
            FunctionsDictionary.Add(new Identifier("figure"), figure);
            FunctionsDictionary.Add(new Identifier("hold"), hold);
            FunctionsDictionary.Add(new Identifier("clf"), clf);
            FunctionsDictionary.Add(new Identifier("axis"), axis);
            FunctionsDictionary.Add(new Identifier("legend"), legend);
            FunctionsDictionary.Add(new Identifier("grid"), grid);
            FunctionsDictionary.Add(new Identifier("xlabel"), xlabel);
            FunctionsDictionary.Add(new Identifier("ylabel"), ylabel);
            FunctionsDictionary.Add(new Identifier("title"), title);
            FunctionsDictionary.Add(new Identifier("plot"), plot);
            FunctionsDictionary.Add(new Identifier("bar"), bar);


            FunctionsDictionary.Add(new Identifier("help"), help);
        }

        //delegat za dictionary
        public delegate List<IQLabValue> f(List<IQLabValue> o);



        
        #region Glavne_Funkcije

        public List<IQLabValue> plus_op(List<IQLabValue> o)
        {
            if (o.Count == 1)
                return uplus(o);
            else
                return plus(o);
        }

        public List<IQLabValue> minus_op(List<IQLabValue> o)
        {
            if (o.Count == 1)
                return uminus(o);
            else
                return minus(o);
        }

        //nije definisano za int64, ostalo je double
        public List<IQLabValue> plus(List<IQLabValue> o)
        {
            //pogledaam da li ima 2 arguenta
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> plus \n Too many input arguments."));

            if (o.Count < 2)
                throw (new NumericalCalculationsException("??? Error using ==> plus \n Not enough input arguments."));

            //proveravam da li je int, posto plus ne radi za int64
            foreach (var el in o)
                if (el.GetEnumType() == IQLabValueType.QInt64NDimArray)
                    throw (new NumericalCalculationsException("??? Undefined function or method 'plus' for input arguments of type 'int64'."));

            //pokusam da konvertujem u float64(Tako MATLAB radi), ukoliko ne mogu prosledjen je CELL, STRUCT ili tako nesto
            if (Helper.canConvertListToEnum(o,IQLabValueType.QFloat64NDimArray))
            {
                //konvertujem u float64
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                //ako je prvi scalar
                if (Helper.checkIfScalar(o.ElementAt(0)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(1).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[0].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;
                        double y1 = of.ElementAt(0).Data[0].Imag;
                        double y2 = of.ElementAt(1).Data[i].Imag;

                        Console.WriteLine("X1 : " + x1 + "X2 : " + x2 + "Y1 : " + y1 + "Y2 : " + y2);

                        vals[i] = new AtomicTypes.QFloat64(x1 + x2, y1 + y2);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals,of.ElementAt(1).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //ako je drugi scalar
                if (Helper.checkIfScalar(o.ElementAt(1)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[0].Real;
                        double y1 = of.ElementAt(0).Data[i].Imag;
                        double y2 = of.ElementAt(1).Data[0].Imag;
                        vals[i] = new AtomicTypes.QFloat64(x1 + x2, y1 + y2);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //proverim da li su istih dimenzija
                if (Helper.checkDimensions(of.ElementAt(0), of.ElementAt(1)) == false)
                    throw( new NumericalCalculationsException("Error using ==> plus \n Matrix dimensions must agree."));
                else
                //istih su dimenzija
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;
                        double y1 = of.ElementAt(0).Data[i].Imag;
                        double y2 = of.ElementAt(1).Data[i].Imag;
                        vals[i] = new AtomicTypes.QFloat64(x1 + x2, y1 + y2);
                    } 
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }
                
                

            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'plus' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o,IQLabValueType.QFloat64NDimArray))+"."));
            }

            
        }

        //nije definisano za int64, ostalo je double
        public List<IQLabValue> minus(List<IQLabValue> o)
        {
            //pogledaam da li ima 2 arguenta
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> minus \n Too many input arguments."));

            if (o.Count < 2)
                throw (new NumericalCalculationsException("??? Error using ==> minus \n Not enough input arguments."));

            //proveravam da li je int, posto plus ne radi za int
            foreach (var el in o)
                if (el.GetEnumType() == IQLabValueType.QInt64NDimArray)
                    throw (new NumericalCalculationsException("??? Undefined function or method 'minus' for input arguments of type 'int64'."));

            //pokusam da konvertujem u float64(Tako MATLAB radi), ukoliko ne mogu prosledjen je CELL, STRUCT ili tako nesto
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //konvertujem u float64
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                //ako je prvi scalar
                if (Helper.checkIfScalar(o.ElementAt(0)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(1).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[0].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;
                        double y1 = of.ElementAt(0).Data[0].Imag;
                        double y2 = of.ElementAt(1).Data[i].Imag;
                        vals[i] = new AtomicTypes.QFloat64(x1 - x2, y1 - y2);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(1).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //ako je drugi scalar
                if (Helper.checkIfScalar(o.ElementAt(1)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[0].Real;
                        double y1 = of.ElementAt(0).Data[i].Imag;
                        double y2 = of.ElementAt(1).Data[0].Imag;
                        vals[i] = new AtomicTypes.QFloat64(x1 - x2, y1 - y2);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //proverim da li su istih dimenzija
                if (Helper.checkDimensions(of.ElementAt(0), of.ElementAt(1)) == false)
                    throw (new NumericalCalculationsException("Error using ==> minus \n Matrix dimensions must agree."));
                else
                // istih su dimenzija
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;
                        double y1 = of.ElementAt(0).Data[i].Imag;
                        double y2 = of.ElementAt(1).Data[i].Imag;
                        vals[i] = new AtomicTypes.QFloat64(x1 - x2, y1 - y2);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }



            }
            else
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'minus' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }
        }

        //za int64 vraca int64
        public List<IQLabValue> uplus(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> uplus \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> uplus \n Not enough input arguments."));

            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //ukoliko je int64, treba to da vrati
                if (o.ElementAt(0).GetEnumType() == IQLabValueType.QInt64NDimArray)
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    res.Add(new QInt64NDimArray(o.ElementAt(0)));
                    return res;
                }
                else
                {
                    //ukoliko je Qboolean ili Qchar, ili Qfloat 
                    List<IQLabValue> resf = new List<IQLabValue>();
                    resf.Add(new QFloat64NDimArray(o.ElementAt(0)));
                    return resf;
                }



            }
            else
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'uplus' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }

        }

        //nije definisano za int64, ostalo je double
        public List<IQLabValue> uminus(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> uminus \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> uminus \n Not enough input arguments."));

            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                QFloat64[] vals = new QFloat64[of.ElementAt(0).Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x = of.ElementAt(0).Data[i].Real;
                    double y = of.ElementAt(0).Data[i].Imag;
                    vals[i] = new QFloat64(-x, -y);
                }

                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize));
                return res;            


            }
            else
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'uminus' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }
        }


        //za int64 nije definisana
        public List<IQLabValue> times(List<IQLabValue> o)
        {
            //pogledaam da li ima 2 arguenta
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> times \n Too many input arguments."));

            if (o.Count < 2)
                throw (new NumericalCalculationsException("??? Error using ==> times \n Not enough input arguments."));

            //proveravam da li je int, posto times ne radi za int64
            foreach (var el in o)
                if (el.GetEnumType() == IQLabValueType.QInt64NDimArray)
                    throw (new NumericalCalculationsException("??? Undefined function or method 'times' for input arguments of type 'int64'."));


            //pokusam da konvertujem u float64(Tako MATLAB radi), ukoliko ne mogu prosledjen je CELL, STRUCT ili tako nesto
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //konvertujem u float64
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                //ako je prvi scalar
                if (Helper.checkIfScalar(o.ElementAt(0)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(1).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[0].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;
                        double y1 = of.ElementAt(0).Data[0].Imag;
                        double y2 = of.ElementAt(1).Data[i].Imag;
                        vals[i] = new AtomicTypes.QFloat64(x1 * x2 - y1 * y2, x1 * y2 + x2 * y1);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(1).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //ako je drugi scalar
                if (Helper.checkIfScalar(o.ElementAt(1)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[0].Real;
                        double y1 = of.ElementAt(0).Data[i].Imag;
                        double y2 = of.ElementAt(1).Data[0].Imag;
                        vals[i] = new AtomicTypes.QFloat64(x1 * x2 - y1 * y2, x1 * y2 + x2 * y1);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //proverim da li su istih dimenzija
                if (Helper.checkDimensions(of.ElementAt(0), of.ElementAt(1)) == false)
                    throw (new NumericalCalculationsException("Error using ==> times \n Matrix dimensions must agree."));
                else
                //istih su dimenzija
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;
                        double y1 = of.ElementAt(0).Data[i].Imag;
                        double y2 = of.ElementAt(1).Data[i].Imag;
                        vals[i] = new AtomicTypes.QFloat64(x1 * x2 - y1 * y2, x1 * y2 + x2 * y1);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }



            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'times' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }

        }

        //PAZNJA
        //posebni slucajevi: (0,0)/(0,0) = Nan
        //                   (x, 0)/(0,0) ...  i sve kombinacije
        public List<IQLabValue> rdivide(List<IQLabValue> o)
        {
            //pogledaam da li ima 2 arguenta
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> rdivide \n Too many input arguments."));

            if (o.Count < 2)
                throw (new NumericalCalculationsException("??? Error using ==> rdivide \n Not enough input arguments."));

         
            //pokusam da konvertujem u float64(Tako MATLAB radi), ukoliko ne mogu prosledjen je CELL, STRUCT ili tako nesto
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //konvertujem u float64
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                //ako je prvi scalar
                if (Helper.checkIfScalar(o.ElementAt(0)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(1).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[0].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;
                        double y1 = of.ElementAt(0).Data[0].Imag;
                        double y2 = of.ElementAt(1).Data[i].Imag;
                        if ((x2 == 0) && (y2 == 0))
                        {
                            if ((x1 == 0) && (y1 == 0))
                            {
                                vals[i] = new AtomicTypes.QFloat64(double.NaN);
                                continue;
                            }

                            if (x1 == 0)
                            {
                                vals[i] = new AtomicTypes.QFloat64(0,y1/0);
                                continue;
                            }
                            if (y1 == 0)
                            {
                                vals[i] = new AtomicTypes.QFloat64(x1 / 0);
                            }
                        }
                        else
                            vals[i] = new AtomicTypes.QFloat64((x1 * x2 + y1 * y2) / (x2 * x2 + y2 * y2), (x2 * y1 - x1 * y2) / (x2 * x2 + y2 * y2));
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(1).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //ako je drugi scalar
                if (Helper.checkIfScalar(o.ElementAt(1)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[0].Real;
                        double y1 = of.ElementAt(0).Data[i].Imag;
                        double y2 = of.ElementAt(1).Data[0].Imag;
                        if ((x2 == 0) && (y2 == 0))
                        {
                            if ((x1 == 0) && (y1 == 0))
                            {
                                vals[i] = new AtomicTypes.QFloat64(double.NaN);
                                continue;
                            }

                            if (x1 == 0)
                            {
                                vals[i] = new AtomicTypes.QFloat64(0, y1 / 0);
                                continue;
                            }
                            if (y1 == 0)
                            {
                                vals[i] = new AtomicTypes.QFloat64(x1 / 0);
                            }
                        }
                        else
                            vals[i] = new AtomicTypes.QFloat64((x1 * x2 + y1 * y2) / (x2 * x2 + y2 * y2), (x2 * y1 - x1 * y2) / (x2 * x2 + y2 * y2));
                    
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //proverim da li su istih dimenzija
                if (Helper.checkDimensions(of.ElementAt(0), of.ElementAt(1)) == false)
                    throw (new NumericalCalculationsException("Error using ==> rdivide \n Matrix dimensions must agree."));
                else
                //istih su dimenzija
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;
                        double y1 = of.ElementAt(0).Data[i].Imag;
                        double y2 = of.ElementAt(1).Data[i].Imag;

                        if ((x2 == 0) && (y2 == 0))
                        {
                            if ((x1 == 0) && (y1 == 0))
                            {
                                vals[i] = new AtomicTypes.QFloat64(double.NaN);
                                continue;
                            }

                            if (x1 == 0)
                            {
                                vals[i] = new AtomicTypes.QFloat64(0, y1 / 0);
                                continue;
                            }
                            if (y1 == 0)
                            {
                                vals[i] = new AtomicTypes.QFloat64(x1 / 0);
                            }
                        }
                        else
                            vals[i] = new AtomicTypes.QFloat64((x1 * x2 + y1 * y2) / (x2 * x2 + y2 * y2), (x2 * y1 - x1 * y2) / (x2 * x2 + y2 * y2));
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }



            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'rdivide' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }
        }

        public List<IQLabValue> ldivide(List<IQLabValue> o)
        {
            //pogledaam da li ima 2 arguenta
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> ldivide \n Too many input arguments."));

            if (o.Count < 2)
                throw (new NumericalCalculationsException("??? Error using ==> ldivide \n Not enough input arguments."));


            //pokusam da konvertujem u float64(Tako MATLAB radi), ukoliko ne mogu prosledjen je CELL, STRUCT ili tako nesto
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //videcu da li se poklapaju dimenzije
                if ((Helper.checkIfScalar(o.ElementAt(0)) == false) && (Helper.checkIfScalar(o.ElementAt(1)) == false) &&
                    (Helper.checkDimensions(new QFloat64NDimArray(o.ElementAt(0)), new QFloat64NDimArray(o.ElementAt(1))) == false))
                    throw (new NumericalCalculationsException("Error using ==> ldivide \n Matrix dimensions must agree."));
                
                //ili se poklapaju, ili su skalari
                List<IQLabValue> newList = new List<IQLabValue>();
                newList.Add(o.ElementAt(1));
                newList.Add(o.ElementAt(0));

                return rdivide(newList);

            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'ldivide' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }
        }

        //NIJE PROVERENO, JAVI NETKU AKO MOZE DA GA PROBA, NE POSTOJI TEST
        public List<IQLabValue> mtimes(List<IQLabValue> o)
        { 
             //pogledaam da li ima 2 arguenta
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> mtimes \n Too many input arguments."));

            if (o.Count < 2)
                throw (new NumericalCalculationsException("??? Error using ==> mtimes \n Not enough input arguments."));

            //proveravam da li je int, posto mtimes ne radi za int64
            foreach (var el in o)
                if (el.GetEnumType() == IQLabValueType.QInt64NDimArray)
                    throw (new NumericalCalculationsException("??? Undefined function or method 'mtimes' for input arguments of type 'int64'."));

            //pokusam da konvertujem u float64(Tako MATLAB radi), ukoliko ne mogu prosledjen je CELL, STRUCT ili tako nesto
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {

                //konvertujem u float64
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                //ako je prvi scalar
                if (Helper.checkIfScalar(o.ElementAt(0)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(1).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[0].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;
                        double y1 = of.ElementAt(0).Data[0].Imag;
                        double y2 = of.ElementAt(1).Data[i].Imag;
                        vals[i] = new AtomicTypes.QFloat64(x1*x2-y1*y2, y1*x2+x1*y2);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(1).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //ako je drugi scalar
                if (Helper.checkIfScalar(o.ElementAt(1)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[0].Real;
                        double y1 = of.ElementAt(0).Data[i].Imag;
                        double y2 = of.ElementAt(1).Data[0].Imag;
                        vals[i] = new AtomicTypes.QFloat64(x1 * x2 - y1 * y2, y1 * x2 + x1 * y2);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //ukoliko nijedan od njih nije skalar, potrebno je proveriti da li su 2d 
                //?PAZNJA: kako mi zapisujemo NdimArray? mislim da je transponovan
                if ((of.ElementAt(0).Dimension > 2) || (of.ElementAt(1).Dimension > 2))
                    throw (new NumericalCalculationsException("??? Error using ==> mtimes \n Inputs must be 2-D, or at least one input must be scalar."));


                //proveriti da li su im iste oddgovarajuce dimenzije 
                if (of.ElementAt(0).DimensionSize[1] != of.ElementAt(1).DimensionSize[0])
                    throw (new NumericalCalculationsException("??? Error using ==> mtimes \n Inner matrix dimensions must agree."));

                //ako su prosle sve provere, mozemo da radimo mnozenje
                QFloat64NDimArray prvi = of.ElementAt(0);
                QFloat64NDimArray drugi = of.ElementAt(1);
                int m = prvi.DimensionSize[0];
                int n = prvi.DimensionSize[1];
                int p = drugi.DimensionSize[1];

                QFloat64NDimArray rez = new QFloat64NDimArray(new int[] { m, p });
                for (int br1 = 0; br1<m; br1++)
                    for (int br2 = 0; br2 < p; br2++)
                    {
                        DoubleComplex pomocni = new DoubleComplex(0, 0);
                        for (int k = 0; k < n; k++)
                        {
                            DoubleComplex c1 = new DoubleComplex(prvi[br1, k].Real, prvi[br1, k].Imag);
                            DoubleComplex c2 = new DoubleComplex(drugi[k, br2].Real, drugi[k, br2].Imag);
                            pomocni = pomocni + c1 * c2;
                        }
                        rez[br1, br2] = new QFloat64(pomocni.Re, pomocni.Im);

                    }

                List<IQLabValue> result = new List<IQLabValue>();
                result.Add(rez);
                return result;
            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'mtimes' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }


        }

        //le == <=
        public List<IQLabValue> le(List<IQLabValue> o)
        {
            //pogledaam da li ima 2 arguenta
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> le \n Too many input arguments."));

            if (o.Count < 2)
                throw (new NumericalCalculationsException("??? Error using ==> le \n Not enough input arguments."));

            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //konvertujem u float64
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                //ako je prvi scalar
                if (Helper.checkIfScalar(o.ElementAt(0)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[of.ElementAt(1).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[0].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;
                        double y1 = of.ElementAt(0).Data[0].Imag;
                        double y2 = of.ElementAt(1).Data[i].Imag;
                        vals[i] = new AtomicTypes.QBoolean(x1<=x2);
                    }
                    QBooleanNDimArray qf = new QBooleanNDimArray(vals, of.ElementAt(1).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //ako je drugi skalar
                if (Helper.checkIfScalar(o.ElementAt(1)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[0].Real;
                        double y1 = of.ElementAt(0).Data[i].Imag;
                        double y2 = of.ElementAt(1).Data[0].Imag;
                        vals[i] = new AtomicTypes.QBoolean(x1 <= x2);
                    }
                    QBooleanNDimArray qf = new QBooleanNDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }


                //proverim da li su istih dimenzija
                if (Helper.checkDimensions(of.ElementAt(0), of.ElementAt(1)) == false)
                    throw (new NumericalCalculationsException("Error using ==> le \n Matrix dimensions must agree."));
                else
                //istih su dimenzija
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;
                        double y1 = of.ElementAt(0).Data[i].Imag;
                        double y2 = of.ElementAt(1).Data[i].Imag;
                        vals[i] = new AtomicTypes.QBoolean(x1 <= x2);
                    }
                    QBooleanNDimArray qf = new QBooleanNDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }
                


            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'le' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }


        }

        //lt == <
        public List<IQLabValue> lt(List<IQLabValue> o)
        {
            //pogledaam da li ima 2 arguenta
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> lt \n Too many input arguments."));

            if (o.Count < 2)
                throw (new NumericalCalculationsException("??? Error using ==> lt \n Not enough input arguments."));

            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //konvertujem u float64
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                //ako je prvi scalar
                if (Helper.checkIfScalar(o.ElementAt(0)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[of.ElementAt(1).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[0].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;
                        double y1 = of.ElementAt(0).Data[0].Imag;
                        double y2 = of.ElementAt(1).Data[i].Imag;
                        vals[i] = new AtomicTypes.QBoolean(x1 < x2);
                    }
                    QBooleanNDimArray qf = new QBooleanNDimArray(vals, of.ElementAt(1).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //ako je drugi skalar
                if (Helper.checkIfScalar(o.ElementAt(1)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[0].Real;
                        double y1 = of.ElementAt(0).Data[i].Imag;
                        double y2 = of.ElementAt(1).Data[0].Imag;
                        vals[i] = new AtomicTypes.QBoolean(x1 < x2);
                    }
                    QBooleanNDimArray qf = new QBooleanNDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }


                //proverim da li su istih dimenzija
                if (Helper.checkDimensions(of.ElementAt(0), of.ElementAt(1)) == false)
                    throw (new NumericalCalculationsException("Error using ==> lt \n Matrix dimensions must agree."));
                else
                //istih su dimenzija
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;
                        double y1 = of.ElementAt(0).Data[i].Imag;
                        double y2 = of.ElementAt(1).Data[i].Imag;
                        vals[i] = new AtomicTypes.QBoolean(x1 < x2);
                    }
                    QBooleanNDimArray qf = new QBooleanNDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }



            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'lt' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }


        }

        //ge == >=
        public List<IQLabValue> ge(List<IQLabValue> o)
        {
            //pogledaam da li ima 2 arguenta
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> ge \n Too many input arguments."));

            if (o.Count < 2)
                throw (new NumericalCalculationsException("??? Error using ==> ge \n Not enough input arguments."));

            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //konvertujem u float64
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                //ako je prvi scalar
                if (Helper.checkIfScalar(o.ElementAt(0)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[of.ElementAt(1).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[0].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;
                        double y1 = of.ElementAt(0).Data[0].Imag;
                        double y2 = of.ElementAt(1).Data[i].Imag;
                        vals[i] = new AtomicTypes.QBoolean(x1 >= x2);
                    }
                    QBooleanNDimArray qf = new QBooleanNDimArray(vals, of.ElementAt(1).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //ako je drugi skalar
                if (Helper.checkIfScalar(o.ElementAt(1)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[0].Real;
                        double y1 = of.ElementAt(0).Data[i].Imag;
                        double y2 = of.ElementAt(1).Data[0].Imag;
                        vals[i] = new AtomicTypes.QBoolean(x1 >= x2);
                    }
                    QBooleanNDimArray qf = new QBooleanNDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }


                //proverim da li su istih dimenzija
                if (Helper.checkDimensions(of.ElementAt(0), of.ElementAt(1)) == false)
                    throw (new NumericalCalculationsException("Error using ==> ge \n Matrix dimensions must agree."));
                else
                //istih su dimenzija
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;
                        double y1 = of.ElementAt(0).Data[i].Imag;
                        double y2 = of.ElementAt(1).Data[i].Imag;
                        vals[i] = new AtomicTypes.QBoolean(x1 >= x2);
                    }
                    QBooleanNDimArray qf = new QBooleanNDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }



            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'ge' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }


        }


        //gt == >
        public List<IQLabValue> gt(List<IQLabValue> o)
        {
            //pogledaam da li ima 2 arguenta
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> gt \n Too many input arguments."));

            if (o.Count < 2)
                throw (new NumericalCalculationsException("??? Error using ==> gt \n Not enough input arguments."));

            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //konvertujem u float64
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                //ako je prvi scalar
                if (Helper.checkIfScalar(o.ElementAt(0)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[of.ElementAt(1).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[0].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;
                        double y1 = of.ElementAt(0).Data[0].Imag;
                        double y2 = of.ElementAt(1).Data[i].Imag;
                        vals[i] = new AtomicTypes.QBoolean(x1 > x2);
                    }
                    QBooleanNDimArray qf = new QBooleanNDimArray(vals, of.ElementAt(1).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //ako je drugi skalar
                if (Helper.checkIfScalar(o.ElementAt(1)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[0].Real;
                        double y1 = of.ElementAt(0).Data[i].Imag;
                        double y2 = of.ElementAt(1).Data[0].Imag;
                        vals[i] = new AtomicTypes.QBoolean(x1 > x2);
                    }
                    QBooleanNDimArray qf = new QBooleanNDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }


                //proverim da li su istih dimenzija
                if (Helper.checkDimensions(of.ElementAt(0), of.ElementAt(1)) == false)
                    throw (new NumericalCalculationsException("Error using ==> gt \n Matrix dimensions must agree."));
                else
                //istih su dimenzija
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;
                        double y1 = of.ElementAt(0).Data[i].Imag;
                        double y2 = of.ElementAt(1).Data[i].Imag;
                        vals[i] = new AtomicTypes.QBoolean(x1 > x2);
                    }
                    QBooleanNDimArray qf = new QBooleanNDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }



            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'gt' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }


        }

        //eq == ==
        public List<IQLabValue> eq(List<IQLabValue> o)
        {
            //pogledaam da li ima 2 arguenta
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> eq \n Too many input arguments."));

            if (o.Count < 2)
                throw (new NumericalCalculationsException("??? Error using ==> eq \n Not enough input arguments."));

            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //konvertujem u float64
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                //ako je prvi scalar
                if (Helper.checkIfScalar(o.ElementAt(0)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[of.ElementAt(1).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[0].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;
                        double y1 = of.ElementAt(0).Data[0].Imag;
                        double y2 = of.ElementAt(1).Data[i].Imag;
                        vals[i] = new AtomicTypes.QBoolean((x1 == x2)&&(y1 == y2));
                    }
                    QBooleanNDimArray qf = new QBooleanNDimArray(vals, of.ElementAt(1).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //ako je drugi skalar
                if (Helper.checkIfScalar(o.ElementAt(1)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[0].Real;
                        double y1 = of.ElementAt(0).Data[i].Imag;
                        double y2 = of.ElementAt(1).Data[0].Imag;
                        vals[i] = new AtomicTypes.QBoolean((x1 == x2) && (y1 == y2));
                    }
                    QBooleanNDimArray qf = new QBooleanNDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }


                //proverim da li su istih dimenzija
                if (Helper.checkDimensions(of.ElementAt(0), of.ElementAt(1)) == false)
                    throw (new NumericalCalculationsException("Error using ==> eq \n Matrix dimensions must agree."));
                else
                //istih su dimenzija
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;
                        double y1 = of.ElementAt(0).Data[i].Imag;
                        double y2 = of.ElementAt(1).Data[i].Imag;
                        vals[i] = new AtomicTypes.QBoolean((x1 == x2) && (y1 == y2));
                    }
                    QBooleanNDimArray qf = new QBooleanNDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }



            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'eq' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }
        }


        //ne == ~=
        public List<IQLabValue> ne(List<IQLabValue> o)
        {
            //pogledaam da li ima 2 arguenta
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> ne \n Too many input arguments."));

            if (o.Count < 2)
                throw (new NumericalCalculationsException("??? Error using ==> ne \n Not enough input arguments."));

            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //konvertujem u float64
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                //ako je prvi scalar
                if (Helper.checkIfScalar(o.ElementAt(0)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[of.ElementAt(1).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[0].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;
                        double y1 = of.ElementAt(0).Data[0].Imag;
                        double y2 = of.ElementAt(1).Data[i].Imag;
                        vals[i] = new AtomicTypes.QBoolean((x1 != x2) || (y1 != y2));
                    }
                    QBooleanNDimArray qf = new QBooleanNDimArray(vals, of.ElementAt(1).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //ako je drugi skalar
                if (Helper.checkIfScalar(o.ElementAt(1)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[0].Real;
                        double y1 = of.ElementAt(0).Data[i].Imag;
                        double y2 = of.ElementAt(1).Data[0].Imag;
                        vals[i] = new AtomicTypes.QBoolean((x1 != x2) || (y1 != y2));
                    }
                    QBooleanNDimArray qf = new QBooleanNDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }


                //proverim da li su istih dimenzija
                if (Helper.checkDimensions(of.ElementAt(0), of.ElementAt(1)) == false)
                    throw (new NumericalCalculationsException("Error using ==> ne \n Matrix dimensions must agree."));
                else
                //istih su dimenzija
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;
                        double y1 = of.ElementAt(0).Data[i].Imag;
                        double y2 = of.ElementAt(1).Data[i].Imag;
                        vals[i] = new AtomicTypes.QBoolean((x1 != x2) || (y1 != y2));
                    }
                    QBooleanNDimArray qf = new QBooleanNDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }



            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'ne' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }
        }


        public List<IQLabValue> and(List<IQLabValue> o)
        {
            //pogledaam da li ima 2 arguenta
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> and \n Too many input arguments."));

            if (o.Count < 2)
                throw (new NumericalCalculationsException("??? Error using ==> and \n Not enough input arguments."));

            

            //pokusam da konvertujem u float64(Tako MATLAB radi), ukoliko ne mogu prosledjen je CELL, STRUCT ili tako nesto
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //proverim da li je ijedan od argumenata kompleksan
                if (Helper.isIQLabValueComplex(o.ElementAt(0)) || Helper.isIQLabValueComplex(o.ElementAt(1)))
                    throw (new NumericalCalculationsException("??? Error using ==> and \n Operands must be real."));

                //konvertujem u float64
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                //napravim QbooleanNdimArraye od njih
                QBooleanNDimArray qbfirst = new QBooleanNDimArray(of.ElementAt(0).DimensionSize);
                for (int i = 0; i < qbfirst.Data.Count(); i++)
                    qbfirst.SetDataElement(i, new QBoolean(of.ElementAt(0).Data[i]));

                QBooleanNDimArray qbsecond = new QBooleanNDimArray(of.ElementAt(1).DimensionSize);
                for (int i = 0; i < qbsecond.Data.Count(); i++)
                    qbsecond.SetDataElement(i, new QBoolean(of.ElementAt(1).Data[i]));


                //ako je prvi scalar
                if (Helper.checkIfScalar(o.ElementAt(0)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[qbsecond.Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        bool x1 = qbfirst.Data[0].Real;
                        bool x2 = qbsecond.Data[i].Real;
                        vals[i] = new AtomicTypes.QBoolean(x1 && x2);
                    }
                    QBooleanNDimArray qb = new QBooleanNDimArray(vals, qbsecond.DimensionSize);
                    res.Add(qb);

                    return res;
                }

                //ako je drugi skalar
                if (Helper.checkIfScalar(o.ElementAt(1)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[qbfirst.Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        bool x1 = qbfirst.Data[i].Real;
                        bool x2 = qbsecond.Data[0].Real;
                        vals[i] = new AtomicTypes.QBoolean(x1 && x2);
                    }
                    QBooleanNDimArray qb = new QBooleanNDimArray(vals, qbfirst.DimensionSize);
                    res.Add(qb);

                    return res;
                }

                //proverim da li su istih dimenzija
                if (Helper.checkDimensions(qbfirst, qbsecond) == false)
                    throw (new NumericalCalculationsException("Error using ==> and \n Matrix dimensions must agree."));
                else
                //istih su dimenzija
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[qbfirst.Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        bool x1 = qbfirst.Data[i].Real;
                        bool x2 = qbsecond.Data[i].Real;
                        vals[i] = new AtomicTypes.QBoolean(x1 && x2);
                    }
                    QBooleanNDimArray qb = new QBooleanNDimArray(vals, qbfirst.DimensionSize);
                    res.Add(qb);

                    return res;
                }


            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'and' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }


        }

        //ne postoji test z or posto sam ga radio potpuno isto kao and
        public List<IQLabValue> or(List<IQLabValue> o)
        {
            //pogledaam da li ima 2 arguenta
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> or \n Too many input arguments."));

            if (o.Count < 2)
                throw (new NumericalCalculationsException("??? Error using ==> or \n Not enough input arguments."));



            //pokusam da konvertujem u float64(Tako MATLAB radi), ukoliko ne mogu prosledjen je CELL, STRUCT ili tako nesto
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //proverim da li je ijedan od argumenata kompleksan
                if (Helper.isIQLabValueComplex(o.ElementAt(0)) || Helper.isIQLabValueComplex(o.ElementAt(1)))
                    throw (new NumericalCalculationsException("??? Error using ==> or \n Operands must be real."));

                //konvertujem u float64
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                //napravim QbooleanNdimArraye od njih
                QBooleanNDimArray qbfirst = new QBooleanNDimArray(of.ElementAt(0).DimensionSize);
                for (int i = 0; i < qbfirst.Data.Count(); i++)
                    qbfirst.SetDataElement(i, new QBoolean(of.ElementAt(0).Data[i]));

                QBooleanNDimArray qbsecond = new QBooleanNDimArray(of.ElementAt(1).DimensionSize);
                for (int i = 0; i < qbsecond.Data.Count(); i++)
                    qbsecond.SetDataElement(i, new QBoolean(of.ElementAt(1).Data[i]));


                //ako je prvi scalar
                if (Helper.checkIfScalar(o.ElementAt(0)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[qbsecond.Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        bool x1 = qbfirst.Data[0].Real;
                        bool x2 = qbsecond.Data[i].Real;
                        vals[i] = new AtomicTypes.QBoolean(x1 || x2);
                    }
                    QBooleanNDimArray qb = new QBooleanNDimArray(vals, qbsecond.DimensionSize);
                    res.Add(qb);

                    return res;
                }

                //ako je drugi skalar
                if (Helper.checkIfScalar(o.ElementAt(1)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[qbfirst.Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        bool x1 = qbfirst.Data[i].Real;
                        bool x2 = qbsecond.Data[0].Real;
                        vals[i] = new AtomicTypes.QBoolean(x1 || x2);
                    }
                    QBooleanNDimArray qb = new QBooleanNDimArray(vals, qbfirst.DimensionSize);
                    res.Add(qb);

                    return res;
                }

                //proverim da li su istih dimenzija
                if (Helper.checkDimensions(qbfirst, qbsecond) == false)
                    throw (new NumericalCalculationsException("Error using ==> or \n Matrix dimensions must agree."));
                else
                //istih su dimenzija
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[qbfirst.Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        bool x1 = qbfirst.Data[i].Real;
                        bool x2 = qbsecond.Data[i].Real;
                        vals[i] = new AtomicTypes.QBoolean(x1 || x2);
                    }
                    QBooleanNDimArray qb = new QBooleanNDimArray(vals, qbfirst.DimensionSize);
                    res.Add(qb);

                    return res;
                }


            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'or' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }


        }

        public List<IQLabValue> xor(List<IQLabValue> o)
        {
            //pogledaam da li ima 2 arguenta
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> xor \n Too many input arguments."));

            if (o.Count < 2)
                throw (new NumericalCalculationsException("??? Error using ==> xor \n Not enough input arguments."));



            //pokusam da konvertujem u float64(Tako MATLAB radi), ukoliko ne mogu prosledjen je CELL, STRUCT ili tako nesto
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //proverim da li je ijedan od argumenata kompleksan
                if (Helper.isIQLabValueComplex(o.ElementAt(0)) || Helper.isIQLabValueComplex(o.ElementAt(1)))
                    throw (new NumericalCalculationsException("??? Error using ==> xor \n Operands must be real."));

                //konvertujem u float64
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                //napravim QbooleanNdimArraye od njih
                QBooleanNDimArray qbfirst = new QBooleanNDimArray(of.ElementAt(0).DimensionSize);
                for (int i = 0; i < qbfirst.Data.Count(); i++)
                    qbfirst.SetDataElement(i, new QBoolean(of.ElementAt(0).Data[i]));

                QBooleanNDimArray qbsecond = new QBooleanNDimArray(of.ElementAt(1).DimensionSize);
                for (int i = 0; i < qbsecond.Data.Count(); i++)
                    qbsecond.SetDataElement(i, new QBoolean(of.ElementAt(1).Data[i]));


                //ako je prvi scalar
                if (Helper.checkIfScalar(o.ElementAt(0)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[qbsecond.Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        bool x1 = qbfirst.Data[0].Real;
                        bool x2 = qbsecond.Data[i].Real;
                        vals[i] = new AtomicTypes.QBoolean(x1 ^ x2);
                    }
                    QBooleanNDimArray qb = new QBooleanNDimArray(vals, qbsecond.DimensionSize);
                    res.Add(qb);

                    return res;
                }

                //ako je drugi skalar
                if (Helper.checkIfScalar(o.ElementAt(1)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[qbfirst.Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        bool x1 = qbfirst.Data[i].Real;
                        bool x2 = qbsecond.Data[0].Real;
                        vals[i] = new AtomicTypes.QBoolean(x1 ^ x2);
                    }
                    QBooleanNDimArray qb = new QBooleanNDimArray(vals, qbfirst.DimensionSize);
                    res.Add(qb);

                    return res;
                }

                //proverim da li su istih dimenzija
                if (Helper.checkDimensions(qbfirst, qbsecond) == false)
                    throw (new NumericalCalculationsException("Error using ==> xor \n Matrix dimensions must agree."));
                else
                //istih su dimenzija
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[qbfirst.Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        bool x1 = qbfirst.Data[i].Real;
                        bool x2 = qbsecond.Data[i].Real;
                        vals[i] = new AtomicTypes.QBoolean(x1 ^ x2);
                    }
                    QBooleanNDimArray qb = new QBooleanNDimArray(vals, qbfirst.DimensionSize);
                    res.Add(qb);

                    return res;
                }


            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'xor' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }


        }


        public List<IQLabValue> not(List<IQLabValue> o)
        {
            //pogledaam da li ima 2 arguenta
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> not \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> not \n Not enough input arguments."));



            //pokusam da konvertujem u float64(Tako MATLAB radi), ukoliko ne mogu prosledjen je CELL, STRUCT ili tako nesto
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //proverim da li je ijedan od argumenata kompleksan
                if (Helper.isIQLabValueComplex(o.ElementAt(0)))
                    throw (new NumericalCalculationsException("??? Error using ==> not \n Operands must be real."));

                //konvertujem u float64
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                //napravim QbooleanNdimArray
                QBooleanNDimArray qbfirst = new QBooleanNDimArray(of.ElementAt(0).DimensionSize);
                for (int i = 0; i < qbfirst.Data.Count(); i++)
                    qbfirst.SetDataElement(i, new QBoolean(of.ElementAt(0).Data[i]));

                
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QBoolean[] vals = new AtomicTypes.QBoolean[qbfirst.Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        bool x1 = qbfirst.Data[i].Real;
                        vals[i] = new AtomicTypes.QBoolean(!x1);
                    }
                    QBooleanNDimArray qb = new QBooleanNDimArray(vals, qbfirst.DimensionSize);
                    res.Add(qb);

                    return res;
                


            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'not' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }


        }


        //mora se proveriti da se operatoru preda 2 argumenta
        public List<IQLabValue> shcircand(List<IQLabValue> o)
        {

            
            //pokusam da konvertujem u float64(Tako MATLAB radi), ukoliko ne mogu prosledjen je CELL, STRUCT ili tako nesto
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //proverim da li je ijedan od argumenata kompleksan
                if (Helper.isIQLabValueComplex(o.ElementAt(0)) || Helper.isIQLabValueComplex(o.ElementAt(1)))
                    throw (new NumericalCalculationsException("??? Complex values cannot be converted to logicals."));
                
                //proverim da li su skalari
                if ((Helper.checkIfScalar(o.ElementAt(0))==false)|| (Helper.checkIfScalar(o.ElementAt(1))==false))
                    throw (new NumericalCalculationsException("??? Operands to the || and && operators must be convertible to logical scalar values."));

                //konvertujem u float64
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                //napravim QbooleanNdimArraye od njih
                QBooleanNDimArray qbfirst = new QBooleanNDimArray(new int[]{1,1});
                qbfirst.SetDataElement(0, new QBoolean(of.ElementAt(0).Data[0]));

                QBooleanNDimArray qbsecond = new QBooleanNDimArray(new int[]{1,1});
                qbsecond.SetDataElement(0, new QBoolean(of.ElementAt(1).Data[0]));


                List<IQLabValue> res = new List<IQLabValue>();

                if (qbfirst.Data[0].Real == false)
                {
                    res.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(false) }, new int[] { 1, 1 }));
                    return res;
                }
                else
                {
                    res.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(qbsecond.Data[0].Real) }, new int[] { 1, 1 }));
                    return res;
                }
                                   

            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Conversion to logical from" + Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "is not possible."));
            }


        }

        //mora se proveriti da se operatoru preda 2 argumenta
        public List<IQLabValue> shcircor(List<IQLabValue> o)
        {


            //pokusam da konvertujem u float64(Tako MATLAB radi), ukoliko ne mogu prosledjen je CELL, STRUCT ili tako nesto
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //proverim da li je ijedan od argumenata kompleksan
                if (Helper.isIQLabValueComplex(o.ElementAt(0)) || Helper.isIQLabValueComplex(o.ElementAt(1)))
                    throw (new NumericalCalculationsException("??? Complex values cannot be converted to logicals."));

                //proverim da li su skalari
                if ((Helper.checkIfScalar(o.ElementAt(0)) == false) || (Helper.checkIfScalar(o.ElementAt(1)) == false))
                    throw (new NumericalCalculationsException("??? Operands to the || and && operators must be convertible to logical scalar values."));

                //konvertujem u float64
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                //napravim QbooleanNdimArraye od njih
                QBooleanNDimArray qbfirst = new QBooleanNDimArray(new int[] { 1, 1 });
                qbfirst.SetDataElement(0, new QBoolean(of.ElementAt(0).Data[0]));

                QBooleanNDimArray qbsecond = new QBooleanNDimArray(new int[] { 1, 1 });
                qbsecond.SetDataElement(0, new QBoolean(of.ElementAt(1).Data[0]));


                List<IQLabValue> res = new List<IQLabValue>();

                if (qbfirst.Data[0].Real == true)
                {
                    res.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(true) }, new int[] { 1, 1 }));
                    return res;
                }
                else
                {
                    res.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(qbsecond.Data[0].Real) }, new int[] { 1, 1 }));
                    return res;
                }


            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Conversion to logical from" + Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "is not possible."));
            }


        }

        
        public List<IQLabValue> abs(List<IQLabValue> o)
        {
            //pogledaam da li ima 1 arguent1
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> abs \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> abs \n Not enough input arguments."));

            //pokusam da konvertujem u float64(Tako MATLAB radi), ukoliko ne mogu prosledjen je CELL, STRUCT ili tako nesto
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                
                //konvertujem u float64
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                //prolazim kroz niz i izvrsim operaciju
                QFloat64[] vals = new QFloat64[of.ElementAt(0).Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = of.ElementAt(0).Data[i].Real;
                    double y1 = of.ElementAt(0).Data[i].Imag;
                    vals[i] = new QFloat64(DoubleComplex.Abs(new DoubleComplex(x1,y1)));
                }

                QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(qf);

                return res;

                

            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'abs' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }


        }

        public List<IQLabValue> acos(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> acos \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> acos \n Not enough input arguments."));

            //matlab radi ovu funkciju samo za float64, ako je int64, logical, char, cell .. vraca gresku
            if (o.ElementAt(0).GetEnumType() == IQLabValueType.QFloat64NDimArray)
            {
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));


                 //prolazim kroz niz i izvrsim operaciju
                QFloat64[] vals = new QFloat64[of.ElementAt(0).Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = of.ElementAt(0).Data[i].Real;
                    double y1 = of.ElementAt(0).Data[i].Imag;
                    DoubleComplex dc = DoubleComplex.Acos(new DoubleComplex(x1,y1));
                    vals[i] = new QFloat64(dc.Re,dc.Im);
                }

                QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(qf);

                return res;

            }
            else
            {
                throw(new NumericalCalculationsException("??? Undefined function or method 'acos' for input arguments of type " +
                    Helper.PrintEnumName(o.ElementAt(0).GetEnumType()) + "."));
            }

        }

        public List<IQLabValue> asin(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> asin \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> asin \n Not enough input arguments."));

            //matlab radi ovu funkciju samo za float64, ako je int64, logical, char, cell .. vraca gresku
            if (o.ElementAt(0).GetEnumType() == IQLabValueType.QFloat64NDimArray)
            {
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));


                //prolazim kroz niz i izvrsim operaciju
                QFloat64[] vals = new QFloat64[of.ElementAt(0).Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = of.ElementAt(0).Data[i].Real;
                    double y1 = of.ElementAt(0).Data[i].Imag;
                    DoubleComplex dc = DoubleComplex.Asin(new DoubleComplex(x1, y1));
                    vals[i] = new QFloat64(dc.Re, dc.Im);
                }

                QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(qf);

                return res;

            }
            else
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'asin' for input arguments of type " +
                    Helper.PrintEnumName(o.ElementAt(0).GetEnumType()) + "."));
            }

        }

        public List<IQLabValue> atan(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> atan \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> atan \n Not enough input arguments."));

            //matlab radi ovu funkciju samo za float64, ako je int64, logical, char, cell .. vraca gresku
            if (o.ElementAt(0).GetEnumType() == IQLabValueType.QFloat64NDimArray)
            {
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));


                //prolazim kroz niz i izvrsim operaciju
                QFloat64[] vals = new QFloat64[of.ElementAt(0).Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = of.ElementAt(0).Data[i].Real;
                    double y1 = of.ElementAt(0).Data[i].Imag;
                    DoubleComplex dc = DoubleComplex.Atan(new DoubleComplex(x1, y1));
                    vals[i] = new QFloat64(dc.Re, dc.Im);
                }

                QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(qf);

                return res;

            }
            else
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'atan' for input arguments of type " +
                    Helper.PrintEnumName(o.ElementAt(0).GetEnumType()) + "."));
            }

        }

        public List<IQLabValue> acosh(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> acosh \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> acosh \n Not enough input arguments."));

            //matlab radi ovu funkciju samo za float64, ako je int64, logical, char, cell .. vraca gresku
            if (o.ElementAt(0).GetEnumType() == IQLabValueType.QFloat64NDimArray)
            {
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));


                //prolazim kroz niz i izvrsim operaciju
                QFloat64[] vals = new QFloat64[of.ElementAt(0).Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = of.ElementAt(0).Data[i].Real;
                    double y1 = of.ElementAt(0).Data[i].Imag;
                    DoubleComplex dc = DoubleComplex.Acosh(new DoubleComplex(x1, y1));
                    vals[i] = new QFloat64(dc.Re, dc.Im);
                }

                QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(qf);

                return res;

            }
            else
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'acosh' for input arguments of type " +
                    Helper.PrintEnumName(o.ElementAt(0).GetEnumType()) + "."));
            }

        }

        public List<IQLabValue> asinh(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> asinh \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> asinh \n Not enough input arguments."));

            //matlab radi ovu funkciju samo za float64, ako je int64, logical, char, cell .. vraca gresku
            if (o.ElementAt(0).GetEnumType() == IQLabValueType.QFloat64NDimArray)
            {
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));


                //prolazim kroz niz i izvrsim operaciju
                QFloat64[] vals = new QFloat64[of.ElementAt(0).Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = of.ElementAt(0).Data[i].Real;
                    double y1 = of.ElementAt(0).Data[i].Imag;
                    DoubleComplex dc = DoubleComplex.Asinh(new DoubleComplex(x1, y1));
                    vals[i] = new QFloat64(dc.Re, dc.Im);
                }

                QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(qf);

                return res;

            }
            else
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'asinh' for input arguments of type " +
                    Helper.PrintEnumName(o.ElementAt(0).GetEnumType()) + "."));
            }

        }

        public List<IQLabValue> atanh(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> atanh \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> atanh \n Not enough input arguments."));

            //matlab radi ovu funkciju samo za float64, ako je int64, logical, char, cell .. vraca gresku
            if (o.ElementAt(0).GetEnumType() == IQLabValueType.QFloat64NDimArray)
            {
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));


                //prolazim kroz niz i izvrsim operaciju
                QFloat64[] vals = new QFloat64[of.ElementAt(0).Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = of.ElementAt(0).Data[i].Real;
                    double y1 = of.ElementAt(0).Data[i].Imag;
                    DoubleComplex dc = DoubleComplex.Atanh(new DoubleComplex(x1, y1));
                    vals[i] = new QFloat64(dc.Re, dc.Im);
                }

                QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(qf);

                return res;

            }
            else
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'atanh' for input arguments of type " +
                    Helper.PrintEnumName(o.ElementAt(0).GetEnumType()) + "."));
            }

        }

        public List<IQLabValue> cos(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> cos \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> cos \n Not enough input arguments."));

            //matlab radi ovu funkciju samo za float64, ako je int64, logical, char, cell .. vraca gresku
            if (o.ElementAt(0).GetEnumType() == IQLabValueType.QFloat64NDimArray)
            {
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));


                //prolazim kroz niz i izvrsim operaciju
                QFloat64[] vals = new QFloat64[of.ElementAt(0).Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = of.ElementAt(0).Data[i].Real;
                    double y1 = of.ElementAt(0).Data[i].Imag;
                    DoubleComplex dc = DoubleComplex.Cos(new DoubleComplex(x1, y1));
                    vals[i] = new QFloat64(dc.Re, dc.Im);
                }

                QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(qf);

                return res;

            }
            else
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'cos' for input arguments of type " +
                    Helper.PrintEnumName(o.ElementAt(0).GetEnumType()) + "."));
            }

        }

        public List<IQLabValue> sin(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> sin \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> sin \n Not enough input arguments."));

            //matlab radi ovu funkciju samo za float64, ako je int64, logical, char, cell .. vraca gresku
            if (o.ElementAt(0).GetEnumType() == IQLabValueType.QFloat64NDimArray)
            {
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));


                //prolazim kroz niz i izvrsim operaciju
                QFloat64[] vals = new QFloat64[of.ElementAt(0).Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = of.ElementAt(0).Data[i].Real;
                    double y1 = of.ElementAt(0).Data[i].Imag;
                    DoubleComplex dc = DoubleComplex.Sin(new DoubleComplex(x1, y1));
                    vals[i] = new QFloat64(dc.Re, dc.Im);
                }

                QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(qf);

                return res;

            }
            else
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'sin' for input arguments of type " +
                    Helper.PrintEnumName(o.ElementAt(0).GetEnumType()) + "."));
            }

        }

        public List<IQLabValue> tan(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> tan \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> tan \n Not enough input arguments."));

            //matlab radi ovu funkciju samo za float64, ako je int64, logical, char, cell .. vraca gresku
            if (o.ElementAt(0).GetEnumType() == IQLabValueType.QFloat64NDimArray)
            {
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));


                //prolazim kroz niz i izvrsim operaciju
                QFloat64[] vals = new QFloat64[of.ElementAt(0).Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = of.ElementAt(0).Data[i].Real;
                    double y1 = of.ElementAt(0).Data[i].Imag;
                    DoubleComplex dc = DoubleComplex.Tan(new DoubleComplex(x1, y1));
                    vals[i] = new QFloat64(dc.Re, dc.Im);
                }

                QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(qf);

                return res;

            }
            else
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'tan' for input arguments of type " +
                    Helper.PrintEnumName(o.ElementAt(0).GetEnumType()) + "."));
            }

        }

        public List<IQLabValue> cosh(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> cosh \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> cosh \n Not enough input arguments."));

            //matlab radi ovu funkciju samo za float64, ako je int64, logical, char, cell .. vraca gresku
            if (o.ElementAt(0).GetEnumType() == IQLabValueType.QFloat64NDimArray)
            {
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));


                //prolazim kroz niz i izvrsim operaciju
                QFloat64[] vals = new QFloat64[of.ElementAt(0).Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = of.ElementAt(0).Data[i].Real;
                    double y1 = of.ElementAt(0).Data[i].Imag;
                    DoubleComplex dc = DoubleComplex.Cosh(new DoubleComplex(x1, y1));
                    vals[i] = new QFloat64(dc.Re, dc.Im);
                }

                QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(qf);

                return res;

            }
            else
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'cosh' for input arguments of type " +
                    Helper.PrintEnumName(o.ElementAt(0).GetEnumType()) + "."));
            }

        }

        public List<IQLabValue> sinh(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> sinh \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> sinh \n Not enough input arguments."));

            //matlab radi ovu funkciju samo za float64, ako je int64, logical, char, cell .. vraca gresku
            if (o.ElementAt(0).GetEnumType() == IQLabValueType.QFloat64NDimArray)
            {
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));


                //prolazim kroz niz i izvrsim operaciju
                QFloat64[] vals = new QFloat64[of.ElementAt(0).Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = of.ElementAt(0).Data[i].Real;
                    double y1 = of.ElementAt(0).Data[i].Imag;
                    DoubleComplex dc = DoubleComplex.Sinh(new DoubleComplex(x1, y1));
                    vals[i] = new QFloat64(dc.Re, dc.Im);
                }

                QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(qf);

                return res;

            }
            else
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'sinh' for input arguments of type " +
                    Helper.PrintEnumName(o.ElementAt(0).GetEnumType()) + "."));
            }

        }

        public List<IQLabValue> tanh(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> tanh \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> tanh \n Not enough input arguments."));

            //matlab radi ovu funkciju samo za float64, ako je int64, logical, char, cell .. vraca gresku
            if (o.ElementAt(0).GetEnumType() == IQLabValueType.QFloat64NDimArray)
            {
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));


                //prolazim kroz niz i izvrsim operaciju
                QFloat64[] vals = new QFloat64[of.ElementAt(0).Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = of.ElementAt(0).Data[i].Real;
                    double y1 = of.ElementAt(0).Data[i].Imag;
                    DoubleComplex dc = DoubleComplex.Tanh(new DoubleComplex(x1, y1));
                    vals[i] = new QFloat64(dc.Re, dc.Im);
                }

                QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(qf);

                return res;

            }
            else
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'tanh' for input arguments of type " +
                    Helper.PrintEnumName(o.ElementAt(0).GetEnumType()) + "."));
            }

        }

        


        //za char i int64 javlja gresku da ne moze u taj tip; za double da trazi nonnegative cele; uint64 i logical vraca double  
        public List<IQLabValue> bitand(List<IQLabValue> o)
        {
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> bitand \n Too many input arguments."));

            if (o.Count < 2)
                throw (new NumericalCalculationsException("??? Error using ==> bitand \n Not enough input arguments."));

            //proverimo da li je char ili int64
            foreach (var el in o)
            {
                IQLabValueType en = el.GetEnumType();
                if ((en == IQLabValueType.QCharNDimArray)||(en == IQLabValueType.QInt64NDimArray))
                    throw (new NumericalCalculationsException("??? Undefined function or method 'bitand' for input arguments of type " +
                    Helper.PrintEnumName(el.GetEnumType()) + "."));

            }

            //proverimo da li je uint64, logical ili double
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //proverim da li je neki kompleksan
                foreach (var el in o)
                {
                    if (Helper.isIQLabValueComplex(el))
                        throw (new NumericalCalculationsException("??? Error using ==> bitand \n Inputs must be real."));
                }

                //ako je double - javi gresku
                foreach (var el in o)
                    if (el.GetEnumType() == IQLabValueType.QFloat64NDimArray)
                        throw(new NumericalCalculationsException("??? Error using ==> bitand \n Inputs must be non-negative integers."));


                

                //znam da imam 2 argumenta, koji su ili tipa logical, ili uint64, mogu ih konvertovati u quint64array
                List<QUInt64NDimArray> oi = new List<QUInt64NDimArray>();
                foreach (var el in o)
                    oi.Add(new QUInt64NDimArray(el));

                

                //ako je prvi scalar
                if (Helper.checkIfScalar(o.ElementAt(0)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[oi.ElementAt(1).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        ulong x1 = oi.ElementAt(0).Data[0].Real;
                        ulong x2 = oi.ElementAt(1).Data[i].Real;
                        ulong y1 = oi.ElementAt(0).Data[0].Imag;
                        ulong y2 = oi.ElementAt(1).Data[i].Imag;
                        vals[i] = new AtomicTypes.QFloat64(x1 & x2);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, oi.ElementAt(1).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //ako je drugi scalar
                if (Helper.checkIfScalar(o.ElementAt(1)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[oi.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        ulong x1 = oi.ElementAt(0).Data[i].Real;
                        ulong x2 = oi.ElementAt(1).Data[0].Real;
                        ulong y1 = oi.ElementAt(0).Data[i].Imag;
                        ulong y2 = oi.ElementAt(1).Data[0].Imag;
                        vals[i] = new AtomicTypes.QFloat64(x1 & x2);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, oi.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //proverim da li su istih dimenzija
                if (Helper.checkDimensions(oi.ElementAt(0), oi.ElementAt(1)) == false)
                    throw (new NumericalCalculationsException("??? Error using ==> bitand \n Inputs must have the same size."));
                else
                //istih su dimenzija
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[oi.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        ulong x1 = oi.ElementAt(0).Data[i].Real;
                        ulong x2 = oi.ElementAt(1).Data[i].Real;
                        ulong y1 = oi.ElementAt(0).Data[i].Imag;
                        ulong y2 = oi.ElementAt(1).Data[i].Imag;
                        vals[i] = new AtomicTypes.QFloat64(x1 & x2);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, oi.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }



            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'bitand' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }

        }

        public List<IQLabValue> bitor(List<IQLabValue> o)
        {
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> bitor \n Too many input arguments."));

            if (o.Count < 2)
                throw (new NumericalCalculationsException("??? Error using ==> bitor \n Not enough input arguments."));

            //proverimo da li je char ili int64
            foreach (var el in o)
            {
                IQLabValueType en = el.GetEnumType();
                if ((en == IQLabValueType.QCharNDimArray) || (en == IQLabValueType.QInt64NDimArray))
                    throw (new NumericalCalculationsException("??? Undefined function or method 'bitor' for input arguments of type " +
                    Helper.PrintEnumName(el.GetEnumType()) + "."));

            }

            //proverimo da li je uint64, logical ili double
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //proverim da li je neki kompleksan
                foreach (var el in o)
                {
                    if (Helper.isIQLabValueComplex(el))
                        throw (new NumericalCalculationsException("??? Error using ==> bitor \n Inputs must be real."));
                }

                //ako je double - javi gresku
                foreach (var el in o)
                    if (el.GetEnumType() == IQLabValueType.QFloat64NDimArray)
                        throw (new NumericalCalculationsException("??? Error using ==> bitor \n Inputs must be non-negative integers."));




                //znam da imam 2 argumenta, koji su ili tipa logical, ili uint64, mogu ih konvertovati u quint64array
                List<QUInt64NDimArray> oi = new List<QUInt64NDimArray>();
                foreach (var el in o)
                    oi.Add(new QUInt64NDimArray(el));



                //ako je prvi scalar
                if (Helper.checkIfScalar(o.ElementAt(0)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[oi.ElementAt(1).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        ulong x1 = oi.ElementAt(0).Data[0].Real;
                        ulong x2 = oi.ElementAt(1).Data[i].Real;
                        ulong y1 = oi.ElementAt(0).Data[0].Imag;
                        ulong y2 = oi.ElementAt(1).Data[i].Imag;
                        vals[i] = new AtomicTypes.QFloat64(x1 | x2);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, oi.ElementAt(1).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //ako je drugi scalar
                if (Helper.checkIfScalar(o.ElementAt(1)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[oi.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        ulong x1 = oi.ElementAt(0).Data[i].Real;
                        ulong x2 = oi.ElementAt(1).Data[0].Real;
                        ulong y1 = oi.ElementAt(0).Data[i].Imag;
                        ulong y2 = oi.ElementAt(1).Data[0].Imag;
                        vals[i] = new AtomicTypes.QFloat64(x1 | x2);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, oi.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //proverim da li su istih dimenzija
                if (Helper.checkDimensions(oi.ElementAt(0), oi.ElementAt(1)) == false)
                    throw (new NumericalCalculationsException("??? Error using ==> bitor \n Inputs must have the same size."));
                else
                //istih su dimenzija
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[oi.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        ulong x1 = oi.ElementAt(0).Data[i].Real;
                        ulong x2 = oi.ElementAt(1).Data[i].Real;
                        ulong y1 = oi.ElementAt(0).Data[i].Imag;
                        ulong y2 = oi.ElementAt(1).Data[i].Imag;
                        vals[i] = new AtomicTypes.QFloat64(x1 | x2);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, oi.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }



            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'bitor' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }

        }


        public List<IQLabValue> bitxor(List<IQLabValue> o)
        {
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> bitxor \n Too many input arguments."));

            if (o.Count < 2)
                throw (new NumericalCalculationsException("??? Error using ==> bitxor \n Not enough input arguments."));

            //proverimo da li je char ili int64
            foreach (var el in o)
            {
                IQLabValueType en = el.GetEnumType();
                if ((en == IQLabValueType.QCharNDimArray) || (en == IQLabValueType.QInt64NDimArray))
                    throw (new NumericalCalculationsException("??? Undefined function or method 'bitxor' for input arguments of type " +
                    Helper.PrintEnumName(el.GetEnumType()) + "."));

            }

            //proverimo da li je uint64, logical ili double
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //proverim da li je neki kompleksan
                foreach (var el in o)
                {
                    if (Helper.isIQLabValueComplex(el))
                        throw (new NumericalCalculationsException("??? Error using ==> bitxor \n Inputs must be real."));
                }

                //ako je double - javi gresku
                foreach (var el in o)
                    if (el.GetEnumType() == IQLabValueType.QFloat64NDimArray)
                        throw (new NumericalCalculationsException("??? Error using ==> bitxor \n Inputs must be non-negative integers."));




                //znam da imam 2 argumenta, koji su ili tipa logical, ili uint64, mogu ih konvertovati u quint64array
                List<QUInt64NDimArray> oi = new List<QUInt64NDimArray>();
                foreach (var el in o)
                    oi.Add(new QUInt64NDimArray(el));



                //ako je prvi scalar
                if (Helper.checkIfScalar(o.ElementAt(0)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[oi.ElementAt(1).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        ulong x1 = oi.ElementAt(0).Data[0].Real;
                        ulong x2 = oi.ElementAt(1).Data[i].Real;
                        ulong y1 = oi.ElementAt(0).Data[0].Imag;
                        ulong y2 = oi.ElementAt(1).Data[i].Imag;
                        vals[i] = new AtomicTypes.QFloat64(x1 ^ x2);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, oi.ElementAt(1).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //ako je drugi scalar
                if (Helper.checkIfScalar(o.ElementAt(1)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[oi.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        ulong x1 = oi.ElementAt(0).Data[i].Real;
                        ulong x2 = oi.ElementAt(1).Data[0].Real;
                        ulong y1 = oi.ElementAt(0).Data[i].Imag;
                        ulong y2 = oi.ElementAt(1).Data[0].Imag;
                        vals[i] = new AtomicTypes.QFloat64(x1 ^ x2);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, oi.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //proverim da li su istih dimenzija
                if (Helper.checkDimensions(oi.ElementAt(0), oi.ElementAt(1)) == false)
                    throw (new NumericalCalculationsException("??? Error using ==> bitxor \n Inputs must have the same size."));
                else
                //istih su dimenzija
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[oi.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        ulong x1 = oi.ElementAt(0).Data[i].Real;
                        ulong x2 = oi.ElementAt(1).Data[i].Real;
                        ulong y1 = oi.ElementAt(0).Data[i].Imag;
                        ulong y2 = oi.ElementAt(1).Data[i].Imag;
                        vals[i] = new AtomicTypes.QFloat64(x1 ^ x2);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, oi.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }



            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'bitxor' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }

        }


        //VAZNO!!! PROCITAJ
        /*
        //ZAVRSITI, KONSULTUJ SE SA NETKOM
        //moze imaati 2 ili jedan argument
        // u  slucaju da su prosledjena 2 elementa: mogu biti uint8, uint16, uint32 i double(koji je ceo broj)
        //u scaju jednog elementa prosledjuje se samo: uint8, uint16, uint32
        public List<IQLabValue> bitcmp(List<IQLabValue> o)
        {
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> bitcmp \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> bitcmp \n Not enough input arguments."));

            if (o.Count == 1)
            {
                //proverimo da li su odgovarajuci tipovi
                IQLabValueType en = o.ElementAt(0).GetEnumType();
                if ((en != IQLabValueType.QUInt8NDimArray)
                        && (en != IQLabValueType.QUInt16NDimArray)
                            && (en != IQLabValueType.QUInt32NDimArray))
                {
                    //ukoliko je doube, provericu da li je svaki element ceo broj
                    if (en == IQLabValueType.QFloat64NDimArray)
                    {
                        throw (new NumericalCalculationsException("??? Error using ==> bitcmp \n Double operands to bitcmp require two inputs."));
                    }
                    else
                    {
                        throw (new NumericalCalculationsException("??? Undefined function or method 'bitcmp' for input arguments of type '" +
                        Helper.PrintEnumName(en) + "'."));
                    }
                }
                //matlab ne prijavljuje gresku ako je kompleksan, vec samo gleda realni deo

                //ako je uint8
                if (en == IQLabValueType.QUInt8NDimArray)
                {
                    QUInt8NDimArray qia = (QUInt8NDimArray)o.ElementAt(0);
                    QFloat64[] vals = new QFloat64[qia.Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        ushort x1 = qia.Data[i].Real;
                        vals[i] = new QFloat64(Math.Pow(2, 8) - 1 - x1);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, qia.DimensionSize);
                    List<IQLabValue> res = new List<IQLabValue>();
                    res.Add(qf);
                    return res;
                }

                //ako je uint16
                if (en == IQLabValueType.QUInt16NDimArray)
                {
                    QUInt16NDimArray qia = (QUInt16NDimArray)o.ElementAt(0);
                    QFloat64[] vals = new QFloat64[qia.Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        ushort x1 = qia.Data[i].Real;
                        vals[i] = new QFloat64(Math.Pow(2,16)-1-x1);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, qia.DimensionSize);
                    List<IQLabValue> res = new List<IQLabValue>();
                    res.Add(qf);
                    return res;
                }

                //ako je uint32
                if (en == IQLabValueType.QUInt32NDimArray)
                {
                    QUInt32NDimArray qia = (QUInt32NDimArray)o.ElementAt(0);
                    QFloat64[] vals = new QFloat64[qia.Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        uint x1 = qia.Data[i].Real;
                        vals[i] = new QFloat64(Math.Pow(2, 32) - 1 - x1);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, qia.DimensionSize);
                    List<IQLabValue> res = new List<IQLabValue>();
                    res.Add(qf);
                    return res;
                }

            }

            if (o.Count == 2)
            {
                //arg moze biti kao prethodno + double koji je ceo broj
                foreach (var el in o)
                {
                    IQLabValueType en = el.GetEnumType();
                    if ((en != IQLabValueType.QUInt8NDimArray)
                        && (en != IQLabValueType.QUInt16NDimArray)
                        && (en != IQLabValueType.QUInt32NDimArray))
                    {
                        //ukoliko je doube, provericu da li je svaki element ceo broj
                        if (en == IQLabValueType.QFloat64NDimArray)
                        {
                            QFloat64NDimArray qf = new QFloat64NDimArray(el);
                            foreach (var q in qf.Data)
                            {
                                if (checkIfRealIsInt(q) == false)
                                    throw(new NumericalCalculationsException("??? Error using ==> bitcmp \n Inputs must be non-negative integers."));
                                  
                            }
                        }
                        else
                        {
                            throw (new NumericalCalculationsException("??? Undefined function or method 'bitcmp' for input arguments of type '" +
                            Helper.PrintEnumName(en) + "'."));
                        }
                    }
                }

                //pretvoricu ih sve u uint64 i sa njima cu raditi, na kraju cu vratit double
                

                //TODO: ZAVRSITI

            }

        }
        */


        public List<IQLabValue> ceil(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> ceil \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> ceil \n Not enough input arguments."));

            //proverimo da li je logical
            foreach (var el in o)
            {
                IQLabValueType en = el.GetEnumType();
                if (en == IQLabValueType.QBooleanNDimArray) 
                    throw (new NumericalCalculationsException("??? Undefined function or method 'ceil' for input arguments of type " +
                    Helper.PrintEnumName(el.GetEnumType()) + "."));

            }

            //da li je int64, uint64, char ili double
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //konvertujem u float64
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                QFloat64[] vals = new QFloat64[of.ElementAt(0).Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = of.ElementAt(0).Data[i].Real;
                    double y1 = of.ElementAt(0).Data[i].Imag;
                    
                    if (x1 == (long)x1)
                        x1--;
                    if (y1 == (long)y1)
                        y1--;
                    vals[i] = new QFloat64(Math.Floor(x1)+1, Math.Floor(y1)+1);
                }

                QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(qf);
                return res;

               
            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'ceil' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }

        }


        public List<IQLabValue> floor(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> floor \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> floor \n Not enough input arguments."));

            //proverimo da li je logical
            foreach (var el in o)
            {
                IQLabValueType en = el.GetEnumType();
                if (en == IQLabValueType.QBooleanNDimArray)
                    throw (new NumericalCalculationsException("??? Undefined function or method 'floor' for input arguments of type " +
                    Helper.PrintEnumName(el.GetEnumType()) + "."));

            }

            //da li je int64, uint64, char ili double
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //konvertujem u float64
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                QFloat64[] vals = new QFloat64[of.ElementAt(0).Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = of.ElementAt(0).Data[i].Real;
                    double y1 = of.ElementAt(0).Data[i].Imag;

                    
                    vals[i] = new QFloat64(Math.Floor(x1), Math.Floor(y1));
                }

                QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(qf);
                return res;


            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'floor' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }

        }

        public List<IQLabValue> round(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> round \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> round \n Not enough input arguments."));

            //proverimo da li je logical
            foreach (var el in o)
            {
                IQLabValueType en = el.GetEnumType();
                if (en == IQLabValueType.QBooleanNDimArray)
                    throw (new NumericalCalculationsException("??? Undefined function or method 'round' for input arguments of type " +
                    Helper.PrintEnumName(el.GetEnumType()) + "."));

            }

            //da li je int64, uint64, char ili double
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //konvertujem u float64
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                QFloat64[] vals = new QFloat64[of.ElementAt(0).Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = of.ElementAt(0).Data[i].Real;
                    double y1 = of.ElementAt(0).Data[i].Imag;

                    double xf = Math.Floor(x1);
                    double yf = Math.Floor(y1);

                    double xc = xf + 1;
                    double yc = yf + 1;

                    double x, y;
                    if (x1 - xf < xc - x1)
                        x = xf;
                    else
                        x = xc;
                    if (y1 - yf < yc - y1)
                        y = yf;
                    else
                        y = yc;

                    vals[i] = new QFloat64(x,y);
                }

                QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(qf);
                return res;


            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'round' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }

        }


        public List<IQLabValue> fix(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> fix \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> fix \n Not enough input arguments."));

            //proverimo da li je logical
            foreach (var el in o)
            {
                IQLabValueType en = el.GetEnumType();
                if (en == IQLabValueType.QBooleanNDimArray)
                    throw (new NumericalCalculationsException("??? Undefined function or method 'fix' for input arguments of type " +
                    Helper.PrintEnumName(el.GetEnumType()) + "."));

            }

            //da li je int64, uint64, char ili double
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //konvertujem u float64
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                QFloat64[] vals = new QFloat64[of.ElementAt(0).Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = of.ElementAt(0).Data[i].Real;
                    double y1 = of.ElementAt(0).Data[i].Imag;

                    double xf = Math.Floor(x1);
                    double yf = Math.Floor(y1);

                    double xc = xf + 1;
                    double yc = yf + 1;

                    double x, y;
                    if (Math.Abs(xf)<Math.Abs(xc))
                        x = xf;
                    else
                        x = xc;
                    if (Math.Abs(yf) < Math.Abs(yc))
                        y = yf;
                    else
                        y = yc;

                    vals[i] = new QFloat64(x, y);
                }

                QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(qf);
                return res;


            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'fix' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }

        }





        public List<IQLabValue> complex(List<IQLabValue> o)
        {
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> complex \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> complex \n Not enough input arguments."));

            //za boolean i char mora da javi gresku
            foreach (var el in o)
            {
                IQLabValueType en = el.GetEnumType();
                if ((en == IQLabValueType.QCharNDimArray) || (en == IQLabValueType.QBooleanNDimArray)||(Helper.isIQLabValueComplex(el)))
                    throw (new NumericalCalculationsException("??? Error using ==> complex \n Real input A must be numeric, real, and full."));
                    
            }
            

            if (Helper.canConvertListToEnum(o, IQLabValueType.QUInt64NDimArray))
            {
                #region ListaUI
                List<QUInt64NDimArray> uil = new List<QUInt64NDimArray>();
                foreach (var el in o)
                    uil.Add(new QUInt64NDimArray(el));

                if (o.Count() == 1)
                {
                    QUInt64NDimArray qui = new QUInt64NDimArray(uil.ElementAt(0));
                    List<IQLabValue> res = new List<IQLabValue>();
                    res.Add(qui);
                    return res;
                }
               
                //inace ima dva elementa

                //ako je prvi skalar
                if (Helper.checkIfScalar(o.ElementAt(0)))
                {
                    
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QUInt64[] vals = new AtomicTypes.QUInt64[uil.ElementAt(1).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        ulong x1 = uil.ElementAt(0).Data[0].Real;
                        ulong x2 = uil.ElementAt(1).Data[i].Real;
                        
                        vals[i] = new AtomicTypes.QUInt64(x1, x2);
                    }
                    QUInt64NDimArray qui = new QUInt64NDimArray(vals, uil.ElementAt(1).DimensionSize);
                    res.Add(qui);

                    return res;
                }

                //ako je drugi skalar
                if (Helper.checkIfScalar(o.ElementAt(1)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QUInt64[] vals = new AtomicTypes.QUInt64[uil.ElementAt(1).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        ulong x1 = uil.ElementAt(0).Data[i].Real;
                        ulong x2 = uil.ElementAt(1).Data[0].Real;

                        vals[i] = new AtomicTypes.QUInt64(x1, x2);
                    }
                    QUInt64NDimArray qui = new QUInt64NDimArray(vals, uil.ElementAt(1).DimensionSize);
                    res.Add(qui);

                    return res;
                }

                //proverim da li su istih dimenzija
                if (Helper.checkDimensions(uil.ElementAt(0), uil.ElementAt(1)) == false)
                    throw (new NumericalCalculationsException("??? Error using ==> complex \n Input arrays must have the same size."));
                else
                //istih su dimenzija
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QUInt64[] vals = new AtomicTypes.QUInt64[uil.ElementAt(1).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        ulong x1 = uil.ElementAt(0).Data[i].Real;
                        ulong x2 = uil.ElementAt(1).Data[i].Real;

                        vals[i] = new AtomicTypes.QUInt64(x1, x2);
                    }
                    QUInt64NDimArray qui = new QUInt64NDimArray(vals, uil.ElementAt(1).DimensionSize);
                    res.Add(qui);

                    return res;
                }

                #endregion

            }
            else
                if (Helper.canConvertListToEnum(o, IQLabValueType.QInt64NDimArray))
                {
                    //provera da li je neki mozda uint64
                    foreach (var el in o)
                    {
                        IQLabValueType en = el.GetEnumType();
                        if (en == IQLabValueType.QUInt64NDimArray)
                            throw (new NumericalCalculationsException("??? Error using ==> complex \n Mixed inputs must either be single and double, or integer and scalardouble. \n All other combinations are no longer allowed."));

                    }

                    #region ListaI
                    List<QInt64NDimArray> il = new List<QInt64NDimArray>();
                    foreach (var el in o)
                        il.Add(new QInt64NDimArray(el));

                    if (o.Count() == 1)
                    {
                        QInt64NDimArray qi = new QInt64NDimArray(il.ElementAt(0));
                        List<IQLabValue> res = new List<IQLabValue>();
                        res.Add(qi);
                        return res;
                    }

                    //inace ima dva elementa

                    //ako je prvi skalar
                    if (Helper.checkIfScalar(o.ElementAt(0)))
                    {

                        List<IQLabValue> res = new List<IQLabValue>();
                        AtomicTypes.QInt64[] vals = new AtomicTypes.QInt64[il.ElementAt(1).Data.Count()];
                        for (int i = 0; i < vals.Count(); i++)
                        {
                            long x1 = il.ElementAt(0).Data[0].Real;
                            long x2 = il.ElementAt(1).Data[i].Real;

                            vals[i] = new AtomicTypes.QInt64(x1, x2);
                        }
                        QInt64NDimArray qi = new QInt64NDimArray(vals, il.ElementAt(1).DimensionSize);
                        res.Add(qi);

                        return res;
                    }

                    //ako je drugi skalar
                    if (Helper.checkIfScalar(o.ElementAt(1)))
                    {
                        List<IQLabValue> res = new List<IQLabValue>();
                        AtomicTypes.QInt64[] vals = new AtomicTypes.QInt64[il.ElementAt(1).Data.Count()];
                        for (int i = 0; i < vals.Count(); i++)
                        {
                            long x1 = il.ElementAt(0).Data[i].Real;
                            long x2 = il.ElementAt(1).Data[0].Real;

                            vals[i] = new AtomicTypes.QInt64(x1, x2);
                        }
                        QInt64NDimArray qi = new QInt64NDimArray(vals, il.ElementAt(1).DimensionSize);
                        res.Add(qi);

                        return res;
                    }

                    //proverim da li su istih dimenzija
                    if (Helper.checkDimensions(il.ElementAt(0), il.ElementAt(1)) == false)
                        throw (new NumericalCalculationsException("??? Error using ==> complex \n Input arrays must have the same size."));
                    else
                    //istih su dimenzija
                    {
                        List<IQLabValue> res = new List<IQLabValue>();
                        AtomicTypes.QInt64[] vals = new AtomicTypes.QInt64[il.ElementAt(1).Data.Count()];
                        for (int i = 0; i < vals.Count(); i++)
                        {
                            long x1 = il.ElementAt(0).Data[i].Real;
                            long x2 = il.ElementAt(1).Data[i].Real;

                            vals[i] = new AtomicTypes.QInt64(x1, x2);
                        }
                        QInt64NDimArray qi = new QInt64NDimArray(vals, il.ElementAt(1).DimensionSize);
                        res.Add(qi);

                        return res;
                    }

                    #endregion
                }
                else
                    if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
                    {

                        //ukoliko prvi nije skalar, drugi ne moze biti uint ili int
                        if (Helper.checkIfScalar(o.ElementAt(0)) == false)
                        {
                            IQLabValueType en = o.ElementAt(1).GetEnumType();
                            if ((en == IQLabValueType.QUInt64NDimArray) || (en == IQLabValueType.QInt64NDimArray))
                                throw (new NumericalCalculationsException("??? Error using ==> complex \n Mixed inputs must either be single and double, or integer and scalardouble. \n All other combinations are no longer allowed."));

                        }

                        //isto za drugi
                        if (Helper.checkIfScalar(o.ElementAt(1)) == false)
                        {
                            IQLabValueType en = o.ElementAt(0).GetEnumType();
                            if ((en == IQLabValueType.QUInt64NDimArray) || (en == IQLabValueType.QInt64NDimArray))
                                throw (new NumericalCalculationsException("??? Error using ==> complex \n Mixed inputs must either be single and double, or integer and scalardouble. \n All other combinations are no longer allowed."));

                        }




                        #region ListaF
                        List<QInt64NDimArray> fl = new List<QInt64NDimArray>();
                        foreach (var el in o)
                            fl.Add(new QInt64NDimArray(el));

                        if (o.Count() == 1)
                        {
                            QFloat64NDimArray qf = new QFloat64NDimArray(fl.ElementAt(0));
                            List<IQLabValue> res = new List<IQLabValue>();
                            res.Add(qf);
                            return res;
                        }

                        //inace ima dva elementa

                        //ako je prvi skalar
                        if (Helper.checkIfScalar(o.ElementAt(0)))
                        {

                            List<IQLabValue> res = new List<IQLabValue>();
                            AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[fl.ElementAt(1).Data.Count()];
                            for (int i = 0; i < vals.Count(); i++)
                            {
                                double x1 = fl.ElementAt(0).Data[0].Real;
                                double x2 = fl.ElementAt(1).Data[i].Real;

                                vals[i] = new AtomicTypes.QFloat64(x1, x2);
                            }
                            QFloat64NDimArray qf = new QFloat64NDimArray(vals, fl.ElementAt(1).DimensionSize);
                            res.Add(qf);

                            return res;
                        }

                        //ako je drugi skalar
                        if (Helper.checkIfScalar(o.ElementAt(1)))
                        {
                            List<IQLabValue> res = new List<IQLabValue>();
                            AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[fl.ElementAt(1).Data.Count()];
                            for (int i = 0; i < vals.Count(); i++)
                            {
                                double x1 = fl.ElementAt(0).Data[i].Real;
                                double x2 = fl.ElementAt(1).Data[0].Real;

                                vals[i] = new AtomicTypes.QFloat64(x1, x2);
                            }
                            QFloat64NDimArray qf = new QFloat64NDimArray(vals, fl.ElementAt(1).DimensionSize);
                            res.Add(qf);

                            return res;
                        }

                        //proverim da li su istih dimenzija
                        if (Helper.checkDimensions(fl.ElementAt(0), fl.ElementAt(1)) == false)
                            throw(new NumericalCalculationsException("??? Error using ==> complex \n Input arrays must have the same size."));
                        else
                        //istih su dimenzija
                        {
                            List<IQLabValue> res = new List<IQLabValue>();
                            AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[fl.ElementAt(1).Data.Count()];
                            for (int i = 0; i < vals.Count(); i++)
                            {
                                double x1 = fl.ElementAt(0).Data[i].Real;
                                double x2 = fl.ElementAt(1).Data[i].Real;

                                vals[i] = new AtomicTypes.QFloat64(x1, x2);
                            }
                            QFloat64NDimArray qf = new QFloat64NDimArray(vals, fl.ElementAt(1).DimensionSize);
                            res.Add(qf);

                            return res;
                        }

                        #endregion
                    }
                    else
                    {
                        throw (new NumericalCalculationsException("??? Error using ==> complex \n Real input A must be numeric, real, and full."));
                    }

        }


        public List<IQLabValue> conj(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> conj \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> conj \n Not enough input arguments."));


            //ne radi za boolean
            foreach (var el in o)
            {
                IQLabValueType en = el.GetEnumType();
                if (en == IQLabValueType.QBooleanNDimArray)
                    throw (new NumericalCalculationsException("??? Undefined function or method 'conj' for input arguments of type " +
                    Helper.PrintEnumName(en) + "."));
            }

            //da li je cell ili struct
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                QFloat64NDimArray qf = new QFloat64NDimArray(o.ElementAt(0));

                QFloat64[] vals = new QFloat64[qf.Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = qf.Data[i].Real;
                    double y1 = qf.Data[i].Imag;
                    vals[i] = new QFloat64(x1, -y1);
                }

                QFloat64NDimArray q = new QFloat64NDimArray(vals, qf.DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(q);
                return res;

            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'conj' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }
        
        }

        public List<IQLabValue> real(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> real \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> real \n Not enough input arguments."));


          

            //da li je cell ili struct
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                QFloat64NDimArray qf = new QFloat64NDimArray(o.ElementAt(0));

                QFloat64[] vals = new QFloat64[qf.Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    vals[i] = new QFloat64(qf.Data[i].Real);
                }

                QFloat64NDimArray q = new QFloat64NDimArray(vals, qf.DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(q);
                return res;

            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'real' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }

        }


        public List<IQLabValue> imag(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> imag \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> imag \n Not enough input arguments."));




            //da li je cell ili struct
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                QFloat64NDimArray qf = new QFloat64NDimArray(o.ElementAt(0));

                QFloat64[] vals = new QFloat64[qf.Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    vals[i] = new QFloat64(qf.Data[i].Imag);
                }

                QFloat64NDimArray q = new QFloat64NDimArray(vals, qf.DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(q);
                return res;

            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'imag' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }

        }


        public List<IQLabValue> exp(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> exp \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> exp \n Not enough input arguments."));

            //exp radi samo double, ukoliko je logical, char, int64, uint64 javlja gresku
            IQLabValueType en = o.ElementAt(0).GetEnumType();
            if ((en == IQLabValueType.QBooleanNDimArray)
                ||(en == IQLabValueType.QCharNDimArray)
                    ||(en == IQLabValueType.QInt64NDimArray)
                    ||(en == IQLabValueType.QUInt64NDimArray))
                throw (new NumericalCalculationsException("??? Undefined function or method 'exp' for input arguments of type " +
                    Helper.PrintEnumName(en) + "."));


            //da li je cell ili struct
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                QFloat64NDimArray qf = new QFloat64NDimArray(o.ElementAt(0));

                QFloat64[] vals = new QFloat64[qf.Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = qf.Data[i].Real;
                    double y1 = qf.Data[i].Imag;
                    DoubleComplex dc = DoubleComplex.Exp(new DoubleComplex(x1, y1));
                    vals[i] = new QFloat64(dc.Re, dc.Im);
                }

                QFloat64NDimArray q = new QFloat64NDimArray(vals, qf.DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(q);
                return res;

            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'exp' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }

        }

        public List<IQLabValue> log(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> log \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> log \n Not enough input arguments."));

            //log radi samo double, ukoliko je logical, char, int64, uint64 javlja gresku
            IQLabValueType en = o.ElementAt(0).GetEnumType();
            if (en != IQLabValueType.QFloat64NDimArray)
                throw (new NumericalCalculationsException("??? Undefined function or method 'log' for input arguments of type " +
                    Helper.PrintEnumName(en) + "."));


            
                QFloat64NDimArray qf = new QFloat64NDimArray(o.ElementAt(0));

                QFloat64[] vals = new QFloat64[qf.Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = qf.Data[i].Real;
                    double y1 = qf.Data[i].Imag;
                    DoubleComplex dc = DoubleComplex.Log(new DoubleComplex(x1, y1));
                    vals[i] = new QFloat64(dc.Re, dc.Im);
                }

                QFloat64NDimArray q = new QFloat64NDimArray(vals, qf.DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(q);
                return res;

           

        }

        public List<IQLabValue> log2(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> log2 \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> log2 \n Not enough input arguments."));

            IQLabValueType en = o.ElementAt(0).GetEnumType();
            if (en != IQLabValueType.QFloat64NDimArray)
                throw (new NumericalCalculationsException("??? Undefined function or method 'log2' for input arguments of type " +
                    Helper.PrintEnumName(en) + "."));


                QFloat64NDimArray qf = new QFloat64NDimArray(o.ElementAt(0));

                QFloat64[] vals = new QFloat64[qf.Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = qf.Data[i].Real;
                    double y1 = qf.Data[i].Imag;
                    DoubleComplex dc = DoubleComplex.Log(new DoubleComplex(x1, y1), new DoubleComplex(2,0));
                    vals[i] = new QFloat64(dc.Re, dc.Im);
                }

                QFloat64NDimArray q = new QFloat64NDimArray(vals, qf.DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(q);
                return res;


        }




        public List<IQLabValue> ischar(List<IQLabValue> o)
        {
            bool p = false;
           
            

            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> isfloat \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> isfloat \n Not enough input arguments."));

            HashSet<IQLabValueType> hs = new HashSet<IQLabValueType>();
            hs.Add(IQLabValueType.QCharNDimArray);

            IQLabValueType en = o.ElementAt(0).GetEnumType();
            if (hs.Contains(en))
            {
                p = true;
            }

            List<IQLabValue> res = new List<IQLabValue>();
            res.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(p) }, new int[] { 1, 1 }));
            return res;
            

        }

        //treba da ispita da li je neka od dimenzija nula
        //moguci tipovi koji se prosledjuju su STructValueArray, Cell, i Boolean, Char, Uint64, Int64, Float64 nizovi
        public List<IQLabValue> isempty(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> isempty \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> isempty \n Not enough input arguments."));

            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                QFloat64NDimArray qf = new QFloat64NDimArray(o.ElementAt(0));

                for (int i = 0; i< qf.Dimension; i++)
                    if (qf.DimensionSize[i] == 0)
                    {
                        List<IQLabValue> res = new List<IQLabValue>();
                        res.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(true) }, new int[] { 1, 1 }));
                        return res;
                    }
                //ako nije pronasao 0
                List<IQLabValue> res1 = new List<IQLabValue>();
                res1.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(false) }, new int[] { 1, 1 }));
                return res1;
            }
            else
            {
                //je cell ili struct
                IQLabValueType en = o.ElementAt(0).GetEnumType();

                if (en == IQLabValueType.QCell)
                {
                    QCell qc = (QCell)o.ElementAt(0);

                    for (int i = 0; i < qc.Dimension; i++)
                        if (qc.DimensionSize[i] == 0)
                        {
                            List<IQLabValue> res = new List<IQLabValue>();
                            res.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(true) }, new int[] { 1, 1 }));
                            return res;
                        }
                   
                    List<IQLabValue> res1 = new List<IQLabValue>();
                    res1.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(false) }, new int[] { 1, 1 }));
                    return res1;
                }

                if (en == IQLabValueType.QStructValueNDimArray)
                {
                    QStructValueNDimArray qs = (QStructValueNDimArray)o.ElementAt(0);

                    for (int i = 0; i < qs.Dimension; i++)
                        if (qs.DimensionSize[i] == 0)
                        {
                            List<IQLabValue> res = new List<IQLabValue>();
                            res.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(true) }, new int[] { 1, 1 }));
                            return res;
                        }

                    List<IQLabValue> res1 = new List<IQLabValue>();
                    res1.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(false) }, new int[] { 1, 1 }));
                    return res1;
                }

                //ako nije ni cell ni struct: onda je function handle ili annimous function, vraca skalar false
                if (en == IQLabValueType.QAnonymousFunction)
                {
                    List<IQLabValue> res1 = new List<IQLabValue>();
                    res1.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(false) }, new int[] { 1, 1 }));
                    return res1;
                }

                if (en == IQLabValueType.QFunctionHandle)
                {
                    List<IQLabValue> res1 = new List<IQLabValue>();
                    res1.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(false) }, new int[] { 1, 1 }));
                    return res1;
                }


                //ovo mislim da nikad ne bi trebalo da se desi
                throw (new NumericalCalculationsException("Please, report this bug."));

            }
        }

        public List<IQLabValue> isfinite(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> isfinite \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> isfinite \n Not enough input arguments."));


            //da li je cell ili struct
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                QFloat64NDimArray qf = new QFloat64NDimArray(o.ElementAt(0));

                QBoolean[] vals = new QBoolean[qf.Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = qf.Data[i].Real;
                    double y1 = qf.Data[i].Imag;
                    bool p1 = (x1 != double.PositiveInfinity) && (x1 != double.NegativeInfinity) && (!double.IsNaN(x1));
                    bool p2 = (y1 != double.PositiveInfinity) && (y1 != double.NegativeInfinity) && (!double.IsNaN(y1));

                    vals[i] = new QBoolean(p1 && p2);
                }

                QBooleanNDimArray q = new QBooleanNDimArray(vals, qf.DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(q);
                return res;

            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'isfinite' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }


        }

        public List<IQLabValue> isfloat(List<IQLabValue> o)
        {
            bool p = false;
            

            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> isfloat \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> isfloat \n Not enough input arguments."));

            HashSet<IQLabValueType> hs = new HashSet<IQLabValueType>();
            hs.Add(IQLabValueType.QFloat32NDimArray);
            hs.Add(IQLabValueType.QFloat64NDimArray);

            IQLabValueType en = o.ElementAt(0).GetEnumType();
            if (hs.Contains(en))
            {
                p = true;
            }

            List<IQLabValue> res = new List<IQLabValue>();
            res.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(p) }, new int[] { 1, 1 }));
            return res;

        }

        public List<IQLabValue> isinf(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> isinf \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> isinf \n Not enough input arguments."));


            //da li je cell ili struct
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                QFloat64NDimArray qf = new QFloat64NDimArray(o.ElementAt(0));

                QBoolean[] vals = new QBoolean[qf.Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = qf.Data[i].Real;
                    double y1 = qf.Data[i].Imag;
                    bool p1 = (x1 == double.PositiveInfinity) || (x1 == double.NegativeInfinity) ;
                    bool p2 = (y1 == double.PositiveInfinity) || (y1 == double.NegativeInfinity);

                    vals[i] = new QBoolean(p1 || p2);
                }

                QBooleanNDimArray q = new QBooleanNDimArray(vals, qf.DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(q);
                return res;

            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'isinf' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }


        }

        public List<IQLabValue> isinteger(List<IQLabValue> o)
        {
            bool p = false;
           

            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> isinteger \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> isinteger \n Not enough input arguments."));

            HashSet<IQLabValueType> hs = new HashSet<IQLabValueType>();
            hs.Add(IQLabValueType.QInt8NDimArray);
            hs.Add(IQLabValueType.QInt16NDimArray);
            hs.Add(IQLabValueType.QInt32NDimArray);
            hs.Add(IQLabValueType.QInt64NDimArray);
            hs.Add(IQLabValueType.QUInt8NDimArray);
            hs.Add(IQLabValueType.QUInt16NDimArray);
            hs.Add(IQLabValueType.QUInt32NDimArray);
            hs.Add(IQLabValueType.QUInt64NDimArray);

            IQLabValueType en = o.ElementAt(0).GetEnumType();
            if (hs.Contains(en))
            {
                p = true;
            }

            List<IQLabValue> res = new List<IQLabValue>();
            res.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(p) }, new int[] { 1, 1 }));
            return res;

        }

        public List<IQLabValue> isletter(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> isletter \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> isletter \n Not enough input arguments."));

            IQLabValueType en = o.ElementAt(0).GetEnumType();

            if (en != IQLabValueType.QCharNDimArray)
            {
                //ukoliko je neki od numerickih ili boolean
                if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
                {
                    QFloat64NDimArray qf = new QFloat64NDimArray(o.ElementAt(0));
                    QBoolean[] vals = new QBoolean[qf.Data.Count()];

                    for (int i = 0; i < vals.Count(); i++)
                    {
                        vals[i] = new QBoolean(false);
                    }
                    QBooleanNDimArray qb = new QBooleanNDimArray(vals, qf.DimensionSize);
                    List<IQLabValue> res = new List<IQLabValue>();
                    res.Add(qb);
                    return res;
                }
                //ukoliko je cell
                if (en == IQLabValueType.QCell)
                {
                    QCell qf = (QCell)o.ElementAt(0);
                    QBoolean[] vals = new QBoolean[qf.Data.Count()];

                    for (int i = 0; i < vals.Count(); i++)
                    {
                        vals[i] = new QBoolean(false);
                    }
                    QBooleanNDimArray qb = new QBooleanNDimArray(vals, qf.DimensionSize);
                    List<IQLabValue> res = new List<IQLabValue>();
                    res.Add(qb);
                    return res;
                }

                //ukoliko je strukt
                if (en == IQLabValueType.QStructValueNDimArray)
                {
                    QStructValueNDimArray qf = (QStructValueNDimArray)o.ElementAt(0);
                    QBoolean[] vals = new QBoolean[qf.Data.Count()];

                    for (int i = 0; i < vals.Count(); i++)
                    {
                        vals[i] = new QBoolean(false);
                    }
                    QBooleanNDimArray qb = new QBooleanNDimArray(vals, qf.DimensionSize);
                    List<IQLabValue> res = new List<IQLabValue>();
                    res.Add(qb);
                    return res;
                }

                //ako nije ni cell ni struct: onda je function handle ili annimous function, vraca skalar false
                if (en == IQLabValueType.QAnonymousFunction)
                {
                    List<IQLabValue> res1 = new List<IQLabValue>();
                    res1.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(false) }, new int[] { 1, 1 }));
                    return res1;
                }

                if (en == IQLabValueType.QFunctionHandle)
                {
                    List<IQLabValue> res1 = new List<IQLabValue>();
                    res1.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(false) }, new int[] { 1, 1 }));
                    return res1;
                }


                //ovo mislim da nikad ne bi trebalo da se desi
                throw (new NumericalCalculationsException("Please, report this bug."));

            }

            //ukoliko je char
            QCharNDimArray qc = new QCharNDimArray(o.ElementAt(0));
            QBoolean[] vals1 = new QBoolean[qc.Data.Count()];

            for (int i = 0; i < vals1.Count(); i++)
            {
                char c = qc.Data[i].Real;
                bool p1 = char.IsLetter(c);
                vals1[i] = new QBoolean(p1);
            }
            QBooleanNDimArray qb1 = new QBooleanNDimArray(vals1, qc.DimensionSize);

            List<IQLabValue> res2 = new List<IQLabValue>();
            res2.Add(qb1);
            return res2;
            


        }

        public List<IQLabValue> islogical(List<IQLabValue> o)
        {
            bool p = false;


            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> islogical \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> islogical \n Not enough input arguments."));

            HashSet<IQLabValueType> hs = new HashSet<IQLabValueType>();
            hs.Add(IQLabValueType.QBooleanNDimArray);
            

            IQLabValueType en = o.ElementAt(0).GetEnumType();
            if (hs.Contains(en))
            {
                p = true;
            }

            List<IQLabValue> res = new List<IQLabValue>();
            res.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(p) }, new int[] { 1, 1 }));
            return res;

        }


        public List<IQLabValue> isnan(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> isnan \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> isnan \n Not enough input arguments."));


            //da li je cell ili struct
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                QFloat64NDimArray qf = new QFloat64NDimArray(o.ElementAt(0));

                QBoolean[] vals = new QBoolean[qf.Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = qf.Data[i].Real;
                    double y1 = qf.Data[i].Imag;
                    bool p1 = (double.IsNaN(x1)) ;
                    bool p2 = (double.IsNaN(y1));

                    vals[i] = new QBoolean(p1 || p2);
                }

                QBooleanNDimArray q = new QBooleanNDimArray(vals, qf.DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(q);
                return res;

            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'isnan' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }


        }

        public List<IQLabValue> isnumeric(List<IQLabValue> o)
        {
            bool p = false;


            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> isnumeric \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> isnumeric \n Not enough input arguments."));

            HashSet<IQLabValueType> hs = new HashSet<IQLabValueType>();
            hs.Add(IQLabValueType.QInt8NDimArray);
            hs.Add(IQLabValueType.QInt16NDimArray);
            hs.Add(IQLabValueType.QInt32NDimArray);
            hs.Add(IQLabValueType.QInt64NDimArray);
            hs.Add(IQLabValueType.QUInt8NDimArray);
            hs.Add(IQLabValueType.QUInt16NDimArray);
            hs.Add(IQLabValueType.QUInt32NDimArray);
            hs.Add(IQLabValueType.QUInt64NDimArray);
            hs.Add(IQLabValueType.QFloat32NDimArray);
            hs.Add(IQLabValueType.QFloat64NDimArray);

            IQLabValueType en = o.ElementAt(0).GetEnumType();
            if (hs.Contains(en))
            {
                p = true;
            }

            List<IQLabValue> res = new List<IQLabValue>();
            res.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(p) }, new int[] { 1, 1 }));
            return res;

        }


        public List<IQLabValue> isreal(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> isreal \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> isreal \n Not enough input arguments."));


            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {

                bool p = !Helper.isIQLabValueComplex(o.ElementAt(0));
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(p) }, new int[] { 1, 1 }));
                return res;
            }
            else
            {
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(false) }, new int[] { 1, 1 }));
                return res;
            }
        }


        public List<IQLabValue> isscalar(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> isscalar \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> isscalar\n Not enough input arguments."));

            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                bool p = Helper.checkIfScalar(o.ElementAt(0));
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(p) }, new int[] { 1, 1 }));
                return res;
            }
            else
            {
                //je cell ili struct
                IQLabValueType en = o.ElementAt(0).GetEnumType();

                if (en == IQLabValueType.QCell)
                {
                    bool p = Helper.checkIfCellIsScalar(o.ElementAt(0));
                    List<IQLabValue> res = new List<IQLabValue>();
                    res.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(p) }, new int[] { 1, 1 }));
                    return res;
                }

                if (en == IQLabValueType.QStructValueNDimArray)
                {
                    bool p = Helper.checkIfStructArrayIsScalar(o.ElementAt(0));
                    List<IQLabValue> res = new List<IQLabValue>();
                    res.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(p) }, new int[] { 1, 1 }));
                    return res;
                }

                //ako nije ni cell ni struct: onda je function handle ili annimous function, vraca skalar true
                if (en == IQLabValueType.QAnonymousFunction)
                {
                    List<IQLabValue> res1 = new List<IQLabValue>();
                    res1.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(true) }, new int[] { 1, 1 }));
                    return res1;
                }

                if (en == IQLabValueType.QFunctionHandle)
                {
                    List<IQLabValue> res1 = new List<IQLabValue>();
                    res1.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(true) }, new int[] { 1, 1 }));
                    return res1;
                }


                //ovo mislim da nikad ne bi trebalo da se desi
                throw (new NumericalCalculationsException("Please, report this bug."));

                //ako nije ni cell ni struct: OVO NE BI TREBALO DA SE DOGODI
                throw (new NumericalCalculationsException("Please, report this bug."));

            }
        
        }


        public List<IQLabValue> isspace(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> isspace \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> isspace \n Not enough input arguments."));

            IQLabValueType en = o.ElementAt(0).GetEnumType();

            if (en != IQLabValueType.QCharNDimArray)
            {
                //ukoliko je neki od numerickih ili boolean
                if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
                {
                    QFloat64NDimArray qf = new QFloat64NDimArray(o.ElementAt(0));
                    QBoolean[] vals = new QBoolean[qf.Data.Count()];

                    for (int i = 0; i < vals.Count(); i++)
                    {
                        vals[i] = new QBoolean(false);
                    }
                    QBooleanNDimArray qb = new QBooleanNDimArray(vals, qf.DimensionSize);
                    List<IQLabValue> res = new List<IQLabValue>();
                    res.Add(qb);
                    return res;
                }
                //ukoliko je cell
                if (en == IQLabValueType.QCell)
                {
                    QCell qf = (QCell)o.ElementAt(0);
                    QBoolean[] vals = new QBoolean[qf.Data.Count()];

                    for (int i = 0; i < vals.Count(); i++)
                    {
                        vals[i] = new QBoolean(false);
                    }
                    QBooleanNDimArray qb = new QBooleanNDimArray(vals, qf.DimensionSize);
                    List<IQLabValue> res = new List<IQLabValue>();
                    res.Add(qb);
                    return res;
                }

                //ukoliko je strukt
                if (en == IQLabValueType.QStructValueNDimArray)
                {
                    QStructValueNDimArray qf = (QStructValueNDimArray)o.ElementAt(0);
                    QBoolean[] vals = new QBoolean[qf.Data.Count()];

                    for (int i = 0; i < vals.Count(); i++)
                    {
                        vals[i] = new QBoolean(false);
                    }
                    QBooleanNDimArray qb = new QBooleanNDimArray(vals, qf.DimensionSize);
                    List<IQLabValue> res = new List<IQLabValue>();
                    res.Add(qb);
                    return res;
                }

                //ako nije ni cell ni struct: onda je function handle ili annimous function, vraca skalar false
                if (en == IQLabValueType.QAnonymousFunction)
                {
                    List<IQLabValue> res1 = new List<IQLabValue>();
                    res1.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(false) }, new int[] { 1, 1 }));
                    return res1;
                }

                if (en == IQLabValueType.QFunctionHandle)
                {
                    List<IQLabValue> res1 = new List<IQLabValue>();
                    res1.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(false) }, new int[] { 1, 1 }));
                    return res1;
                }


                //ovo mislim da nikad ne bi trebalo da se desi
                throw (new NumericalCalculationsException("Please, report this bug."));

            }

            //ukoliko je char
            QCharNDimArray qc = new QCharNDimArray(o.ElementAt(0));
            QBoolean[] vals1 = new QBoolean[qc.Data.Count()];

            for (int i = 0; i < vals1.Count(); i++)
            {
                char c = qc.Data[i].Real;
                bool p1 = char.IsWhiteSpace(c);
                vals1[i] = new QBoolean(p1);
            }
            QBooleanNDimArray qb1 = new QBooleanNDimArray(vals1, qc.DimensionSize);

            List<IQLabValue> res2 = new List<IQLabValue>();
            res2.Add(qb1);
            return res2;



        }

        public List<IQLabValue> mod(List<IQLabValue> o)
        {
            //pogledaam da li ima 2 arguenta
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> mod \n Too many input arguments."));

            if (o.Count < 2)
                throw (new NumericalCalculationsException("??? Error using ==> mod \n Not enough input arguments."));

            //proveravam posto plus ne radi za int64, uint64 i logical
            foreach (var el in o)
            {
                IQLabValueType en = el.GetEnumType();
                if ((en == IQLabValueType.QInt64NDimArray)||(en == IQLabValueType.QUInt64NDimArray)||(en == IQLabValueType.QBooleanNDimArray))
                    throw (new NumericalCalculationsException("??? Undefined function or method 'mod' for input arguments of type "+Helper.PrintEnumName(en)+"."));
            }


            //pokusam da konvertujem u float64(Tako MATLAB radi), ukoliko ne mogu prosledjen je CELL, STRUCT ili tako nesto
            if (Helper.canConvertListToEnum(o,IQLabValueType.QFloat64NDimArray))
            {
                //proverim da li su kompleksni
                foreach (var el in o)
                {
                    if (Helper.isIQLabValueComplex(el))
                        throw (new NumericalCalculationsException("??? Error using ==> mod \n Arguments must be real."));
                }

                //konvertujem u float64
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                //ako je prvi scalar
                if (Helper.checkIfScalar(o.ElementAt(0)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(1).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[0].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;

                        double p;
                        if (x2 == 0)
                            p = x1;
                        else if (x2 == x1)
                            p = 0;
                        else
                            p = x1 % x2;

                        if (Math.Sign(x1) != Math.Sign(x2))
                            p = p + x2;

                        vals[i] = new AtomicTypes.QFloat64(p);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals,of.ElementAt(1).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //ako je drugi scalar
                if (Helper.checkIfScalar(o.ElementAt(1)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[0].Real;
                        double p;
                        if (x2 == 0)
                            p = x1;
                        else if (x2 == x1)
                            p = 0;
                        else
                            p = x1 % x2;

                        if (Math.Sign(x1) != Math.Sign(x2))
                            p = p + x2;

                        vals[i] = new AtomicTypes.QFloat64(p);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //proverim da li su istih dimenzija
                if (Helper.checkDimensions(of.ElementAt(0), of.ElementAt(1)) == false)
                    throw( new NumericalCalculationsException("Error using ==> mod \n Matrix dimensions must agree."));
                else
                //istih su dimenzija
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;
                        double p;
                        if (x2 == 0)
                            p = x1;
                        else if (x2 == x1)
                            p = 0;
                        else
                            p = x1 % x2;

                        if (Math.Sign(x1) != Math.Sign(x2))
                            p = p + x2;

                        vals[i] = new AtomicTypes.QFloat64(p);
                    } 
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }
                
                

            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'mod' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o,IQLabValueType.QFloat64NDimArray))+"."));
            }

            
        }

        public List<IQLabValue> ndims(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> ndims \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> ndims \n Not enough input arguments."));

            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                QFloat64NDimArray qf = new QFloat64NDimArray(o.ElementAt(0));

                
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(new QFloat64NDimArray(new QFloat64[] { new QFloat64(qf.Dimension) }, new int[] { 1, 1 }));
                return res;
            }
            else
            {
                //je cell ili struct
                IQLabValueType en = o.ElementAt(0).GetEnumType();

                if (en == IQLabValueType.QCell)
                {
                    QCell qc = (QCell)o.ElementAt(0);

                    List<IQLabValue> res = new List<IQLabValue>();
                    res.Add(new QFloat64NDimArray(new QFloat64[] { new QFloat64(qc.Dimension) }, new int[] { 1, 1 }));
                    return res;
                }

                if (en == IQLabValueType.QStructValueNDimArray)
                {
                    QStructValueNDimArray qs = (QStructValueNDimArray)o.ElementAt(0);

                    List<IQLabValue> res = new List<IQLabValue>();
                    res.Add(new QFloat64NDimArray(new QFloat64[] { new QFloat64(qs.Dimension) }, new int[] { 1, 1 }));
                    return res;
                }

                //ako nije ni cell ni struct: onda je function handle ili anonimous function, vraca skalar 2
                if (en == IQLabValueType.QAnonymousFunction)
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    res.Add(new QFloat64NDimArray(new QFloat64[] { new QFloat64(2) }, new int[] { 1, 1 }));
                    return res;
                }

                if (en == IQLabValueType.QFunctionHandle)
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    res.Add(new QFloat64NDimArray(new QFloat64[] { new QFloat64(2) }, new int[] { 1, 1 }));
                    return res;
                }


                //ovo mislim da nikad ne bi trebalo da se desi
                throw (new NumericalCalculationsException("Please, report this bug."));

            }
        }

        public List<IQLabValue> nnz(List<IQLabValue> o)
        {
            //pogledaam da li ima 2 arguenta
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> nnz \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> nnz \n Not enough input arguments."));

           
            //pokusam da konvertujem u float64(Tako MATLAB radi), ukoliko ne mogu prosledjen je CELL, STRUCT ili tako nesto
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                QFloat64NDimArray qf = new QFloat64NDimArray(o.ElementAt(0));
                int count = 0;

                for (int i = 0; i < qf.Data.Count(); i++)
                {
                    double x1 = qf.Data[i].Real;
                    double y1 = qf.Data[i].Imag;
                    if ((x1 != 0) || (y1 != 0)) count++;
                }

                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(new QFloat64NDimArray(new QFloat64[] { new QFloat64(count) }, new int[] { 1, 1 }));
                return res;

               
            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'nnz' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }


        }

        //radi samo za float64
        public List<IQLabValue> pow2(List<IQLabValue> o)
        {
            //pogledaam da li ima 2 arguenta
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> pow2 \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> pow2 \n Not enough input arguments."));

            //proverimo da li je float64
            foreach (var el in o)
            {
                IQLabValueType en = el.GetEnumType();
                if (en!= IQLabValueType.QFloat64NDimArray)
                    throw (new NumericalCalculationsException("??? Undefined function or method 'pow2' for input arguments of type " + Helper.PrintEnumName(en) + "."));
            }

            if (o.Count() == 1)
            {
                QFloat64NDimArray qf = new QFloat64NDimArray(o.ElementAt(0));
                QFloat64[] vals = new QFloat64[qf.Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = qf.Data[i].Real;
                    double y1 = qf.Data[i].Imag;
                    DoubleComplex dc = DoubleComplex.Pow(new DoubleComplex(2, 0), new DoubleComplex(x1, y1));
                    vals[i] = new QFloat64(dc.Re, dc.Im);

                }

                QFloat64NDimArray qf1 = new QFloat64NDimArray(vals, qf.DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(qf1);
                return res;
            }
            else
            {
                //konvertujem u float64
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                //ako je prvi scalar
                if (Helper.checkIfScalar(o.ElementAt(0)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(1).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[0].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;
                        double y1 = of.ElementAt(0).Data[0].Imag;
                        double y2 = of.ElementAt(1).Data[i].Imag;
                        DoubleComplex dc = (new DoubleComplex(x1, 0)) * DoubleComplex.Pow(new DoubleComplex(2, 0), new DoubleComplex(x2, 0)); 
                        vals[i] = new AtomicTypes.QFloat64(dc.Re, dc.Im);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(1).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //ako je drugi scalar
                if (Helper.checkIfScalar(o.ElementAt(1)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[0].Real;
                        double y1 = of.ElementAt(0).Data[i].Imag;
                        double y2 = of.ElementAt(1).Data[0].Imag;
                        DoubleComplex dc = (new DoubleComplex(x1, 0)) * DoubleComplex.Pow(new DoubleComplex(2, 0), new DoubleComplex(x2, 0)); 
                        vals[i] = new AtomicTypes.QFloat64(dc.Re, dc.Im);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //proverim da li su istih dimenzija
                if (Helper.checkDimensions(of.ElementAt(0), of.ElementAt(1)) == false)
                    throw (new NumericalCalculationsException("Error using ==> pow2 \n Matrix dimensions must agree."));
                else
                //istih su dimenzija
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;
                        double y1 = of.ElementAt(0).Data[i].Imag;
                        double y2 = of.ElementAt(1).Data[i].Imag;
                        DoubleComplex dc = (new DoubleComplex(x1, 0)) * DoubleComplex.Pow(new DoubleComplex(2, 0), new DoubleComplex(x2, 0));
                        vals[i] = new AtomicTypes.QFloat64(dc.Re, dc.Im);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }

            }
        }


        public List<IQLabValue> power(List<IQLabValue> o)
        {
            //pogledaam da li ima 2 arguenta
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> power \n Too many input arguments."));

            if (o.Count < 2)
                throw (new NumericalCalculationsException("??? Error using ==> power \n Not enough input arguments."));

            //proveravam da li je int, posto plus ne radi za int64
            foreach (var el in o)
            {
                IQLabValueType en = o.ElementAt(0).GetEnumType();
                if ((en == IQLabValueType.QInt64NDimArray)||(en == IQLabValueType.QUInt64NDimArray)||(en == IQLabValueType.QBooleanNDimArray))
                    throw (new NumericalCalculationsException("??? Undefined function or method 'plus' for input arguments of type "+Helper.PrintEnumName(en)+"."));
            }

            //pokusam da konvertujem u float64(Tako MATLAB radi), ukoliko ne mogu prosledjen je CELL, STRUCT ili tako nesto
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //konvertujem u float64
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                //ako je prvi scalar
                if (Helper.checkIfScalar(o.ElementAt(0)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(1).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[0].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;
                        double y1 = of.ElementAt(0).Data[0].Imag;
                        double y2 = of.ElementAt(1).Data[i].Imag;
                        DoubleComplex dc = DoubleComplex.Pow(new DoubleComplex(x1,y1), new DoubleComplex(x2,y2));
                        vals[i] = new AtomicTypes.QFloat64(dc.Re, dc.Im);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(1).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //ako je drugi scalar
                if (Helper.checkIfScalar(o.ElementAt(1)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[0].Real;
                        double y1 = of.ElementAt(0).Data[i].Imag;
                        double y2 = of.ElementAt(1).Data[0].Imag;
                        DoubleComplex dc = DoubleComplex.Pow(new DoubleComplex(x1, y1), new DoubleComplex(x2, y2));
                        vals[i] = new AtomicTypes.QFloat64(dc.Re, dc.Im);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //proverim da li su istih dimenzija
                if (Helper.checkDimensions(of.ElementAt(0), of.ElementAt(1)) == false)
                    throw (new NumericalCalculationsException("Error using ==> power \n Matrix dimensions must agree."));
                else
                //istih su dimenzija
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;
                        double y1 = of.ElementAt(0).Data[i].Imag;
                        double y2 = of.ElementAt(1).Data[i].Imag;
                        DoubleComplex dc = DoubleComplex.Pow(new DoubleComplex(x1, y1), new DoubleComplex(x2, y2));
                        vals[i] = new AtomicTypes.QFloat64(dc.Re, dc.Im);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }



            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'power' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }


        }


        public List<IQLabValue> reallog(List<IQLabValue> o)
        {
            //pogledaam da li ima 1 arg
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> reallog \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> reallog \n Not enough input arguments."));

            //reallog radi samo double, ukoliko je logical, char, int64, uint64 javlja gresku, ili cell i struct i...
            IQLabValueType en = o.ElementAt(0).GetEnumType();
            if (en != IQLabValueType.QFloat64NDimArray)
                throw (new NumericalCalculationsException("??? Undefined function or method 'reallog' for input arguments of type " +
                    Helper.PrintEnumName(en) + "."));

            //proverimo da li postoji konpleksan
            if (Helper.isIQLabValueComplex(o.ElementAt(0)))
                throw (new NumericalCalculationsException("??? Error using ==> reallog \n Reallog produced complex result."));

            bool p = false;

            //proverimo da li postoji realan negativan
            QFloat64NDimArray qf = new QFloat64NDimArray(o.ElementAt(0));
            for (int i = 0; i < qf.Data.Count(); i++)
            {
                double x1 = qf.Data[i].Real;
                if (x1 <= 0)
                {
                    p = true;
                    break;
                }
            }
            if (p)
                throw (new NumericalCalculationsException("??? Error using ==> reallog \n Reallog produced complex result."));

          
            //brojevi su realni i pozitivni
            QFloat64[] vals = new QFloat64[qf.Data.Count()];
            for (int i = 0; i < vals.Count(); i++)
            {
                double x1 = qf.Data[i].Real;
                vals[i] = new QFloat64(Math.Log(x1));
            }
            List<IQLabValue> res = new List<IQLabValue>();
            res.Add(new QFloat64NDimArray(vals, qf.DimensionSize));
            return res;


        }


        public List<IQLabValue> realpow(List<IQLabValue> o)
        {
            //pogledaam da li ima 2 arguenta
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> realpow \n Too many input arguments."));

            if (o.Count < 2)
                throw (new NumericalCalculationsException("??? Error using ==> realpow \n Not enough input arguments."));

            //reallog radi samo double, ukoliko je logical, char, int64, uint64 javlja gresku, ili cell i struct i...
            foreach (var el in o)
            {
                IQLabValueType en = el.GetEnumType();
                if (en != IQLabValueType.QFloat64NDimArray)
                    throw (new NumericalCalculationsException("??? Undefined function or method 'realpow' for input arguments of type " +
                        Helper.PrintEnumName(en) + "."));
            }

            //proverimo da li postoji konpleksan
            foreach (var el in o)
            {
                if (Helper.isIQLabValueComplex(el))
                    throw (new NumericalCalculationsException("??? Error using ==> realpow \n Realpow produced complex result."));
            }


            //konvertujem u float64
            List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
            foreach (var oel in o)
                of.Add(new QFloat64NDimArray(oel));

            //ako je prvi scalar
            if (Helper.checkIfScalar(o.ElementAt(0)))
            {
                List<IQLabValue> res = new List<IQLabValue>();
                AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(1).Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = of.ElementAt(0).Data[0].Real;
                    double x2 = of.ElementAt(1).Data[i].Real;
                    
                    vals[i] = new AtomicTypes.QFloat64(Math.Pow(x1,x2));
                }
                QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(1).DimensionSize);
                res.Add(qf);

                return res;
            }

            //ako je drugi scalar
            if (Helper.checkIfScalar(o.ElementAt(1)))
            {
                List<IQLabValue> res = new List<IQLabValue>();
                AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(0).Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = of.ElementAt(0).Data[i].Real;
                    double x2 = of.ElementAt(1).Data[0].Real;

                    vals[i] = new AtomicTypes.QFloat64(Math.Pow(x1, x2));
                }
                QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                res.Add(qf);

                return res;
            }

            //proverim da li su istih dimenzija
            if (Helper.checkDimensions(of.ElementAt(0), of.ElementAt(1)) == false)
                throw (new NumericalCalculationsException("Error using ==> realpow \n Matrix dimensions must agree."));
            else
            //istih su dimenzija
            {
                List<IQLabValue> res = new List<IQLabValue>();
                AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(0).Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = of.ElementAt(0).Data[i].Real;
                    double x2 = of.ElementAt(1).Data[i].Real;

                    vals[i] = new AtomicTypes.QFloat64(Math.Pow(x1, x2));
                }
                QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                res.Add(qf);

                return res;
            }
                
                


        }


        public List<IQLabValue> realsqrt(List<IQLabValue> o)
        {
            //pogledaam da li ima 1 arg
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> realsqrt \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> realsqrt \n Not enough input arguments."));

            //realsqrt radi samo double, ukoliko je logical, char, int64, uint64 javlja gresku, ili cell i struct i...
            IQLabValueType en = o.ElementAt(0).GetEnumType();
            if (en != IQLabValueType.QFloat64NDimArray)
                throw (new NumericalCalculationsException("??? Undefined function or method 'realsqrt' for input arguments of type " +
                    Helper.PrintEnumName(en) + "."));

            //proverimo da li postoji kompleksan
            if (Helper.isIQLabValueComplex(o.ElementAt(0)))
                throw (new NumericalCalculationsException("??? Error using ==> realsqrt \n Realsqrt produced complex result."));

            bool p = false;

            //proverimo da li postoji realan negativan
            QFloat64NDimArray qf = new QFloat64NDimArray(o.ElementAt(0));
            for (int i = 0; i < qf.Data.Count(); i++)
            {
                double x1 = qf.Data[i].Real;
                if (x1 <= 0)
                {
                    p = true;
                    break;
                }
            }
            if (p)
                throw (new NumericalCalculationsException("??? Error using ==> realsqrt \n Reallog produced complex result."));


            //brojevi su realni i pozitivni
            QFloat64[] vals = new QFloat64[qf.Data.Count()];
            for (int i = 0; i < vals.Count(); i++)
            {
                double x1 = qf.Data[i].Real;
                vals[i] = new QFloat64(Math.Sqrt(x1));
            }
            List<IQLabValue> res = new List<IQLabValue>();
            res.Add(new QFloat64NDimArray(vals, qf.DimensionSize));
            return res;


        }

        public List<IQLabValue> rem(List<IQLabValue> o)
        {
            //pogledaam da li ima 2 arguenta
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> rem \n Too many input arguments."));

            if (o.Count < 2)
                throw (new NumericalCalculationsException("??? Error using ==> rem \n Not enough input arguments."));

            //proveravam posto plus ne radi za int64, uint64 i logical
            foreach (var el in o)
            {
                IQLabValueType en = el.GetEnumType();
                if ((en == IQLabValueType.QInt64NDimArray) || (en == IQLabValueType.QUInt64NDimArray) || (en == IQLabValueType.QBooleanNDimArray))
                    throw (new NumericalCalculationsException("??? Undefined function or method 'rem' for input arguments of type " + Helper.PrintEnumName(en) + "."));
            }


            //pokusam da konvertujem u float64(Tako MATLAB radi), ukoliko ne mogu prosledjen je CELL, STRUCT ili tako nesto
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //proverim da li su kompleksni
                foreach (var el in o)
                {
                    if (Helper.isIQLabValueComplex(el))
                        throw (new NumericalCalculationsException("??? Error using ==> rem \n Arguments must be real."));
                }

                //konvertujem u float64
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                //ako je prvi scalar
                if (Helper.checkIfScalar(o.ElementAt(0)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(1).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[0].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;

                        double p;
                        if (x2 == 0)
                            p = double.NaN;
                        else if (x2 == x1)
                            p = 0;
                        else
                            p = x1 % x2;

                       

                        vals[i] = new AtomicTypes.QFloat64(p);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(1).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //ako je drugi scalar
                if (Helper.checkIfScalar(o.ElementAt(1)))
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[0].Real;
                        double p;
                        if (x2 == 0)
                            p = double.NaN;
                        else if (x2 == x1)
                            p = 0;
                        else
                            p = x1 % x2;

                        
                        vals[i] = new AtomicTypes.QFloat64(p);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }

                //proverim da li su istih dimenzija
                if (Helper.checkDimensions(of.ElementAt(0), of.ElementAt(1)) == false)
                    throw (new NumericalCalculationsException("Error using ==> rem \n Matrix dimensions must agree."));
                else
                //istih su dimenzija
                {
                    List<IQLabValue> res = new List<IQLabValue>();
                    AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(0).Data.Count()];
                    for (int i = 0; i < vals.Count(); i++)
                    {
                        double x1 = of.ElementAt(0).Data[i].Real;
                        double x2 = of.ElementAt(1).Data[i].Real;
                        double p;
                        if (x2 == 0)
                            p = double.NaN;
                        else if (x2 == x1)
                            p = 0;
                        else
                            p = x1 % x2;


                        vals[i] = new AtomicTypes.QFloat64(p);
                    }
                    QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                    res.Add(qf);

                    return res;
                }



            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'rem' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }


        }


        public List<IQLabValue> sign(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> sign \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> sign \n Not enough input arguments."));

            //provera da li je int64, uint64 ili boolean
            foreach (var el in o)
            {
                IQLabValueType en = el.GetEnumType();
                if ((en == IQLabValueType.QInt64NDimArray ) || (en == IQLabValueType.QUInt16NDimArray) || (en == IQLabValueType.QBooleanNDimArray))
                    throw (new NumericalCalculationsException("??? Undefined function or method 'sign' for input arguments of type "+ Helper.PrintEnumName(en) + "."));
            }


            //da li je cell ili struct
            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                QFloat64NDimArray qf = new QFloat64NDimArray(o.ElementAt(0));

                QFloat64[] vals = new QFloat64[qf.Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = qf.Data[i].Real;
                    double y1 = qf.Data[i].Imag;

                    DoubleComplex dc;

                    if (y1 == 0)
                    {
                        if (x1 > 0)
                            dc = new DoubleComplex(1, 0);
                        else if (x1 == 0)
                            dc = new DoubleComplex(0, 0);
                            else 
                                dc = new DoubleComplex(-1, 0);
                    }
                    else
                    {
                        dc = (new DoubleComplex(x1, y1)) / DoubleComplex.Abs(new DoubleComplex(x1, y1));
                    }

                    vals[i] = new QFloat64(dc.Re, dc.Im);
                }

                QFloat64NDimArray q = new QFloat64NDimArray(vals, qf.DimensionSize);
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(q);
                return res;

            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'sign' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }

        }

        public List<IQLabValue> sqrt(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> sqrt \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> sqrt \n Not enough input arguments."));

            //sqrt radi samo double, ukoliko je logical, char, int64, uint64 javlja gresku
            IQLabValueType en = o.ElementAt(0).GetEnumType();
            if (en != IQLabValueType.QFloat64NDimArray)
                throw (new NumericalCalculationsException("??? Undefined function or method 'sqrt' for input arguments of type " +
                    Helper.PrintEnumName(en) + "."));



            QFloat64NDimArray qf = new QFloat64NDimArray(o.ElementAt(0));

            QFloat64[] vals = new QFloat64[qf.Data.Count()];
            for (int i = 0; i < vals.Count(); i++)
            {
                double x1 = qf.Data[i].Real;
                double y1 = qf.Data[i].Imag;
                DoubleComplex dc = DoubleComplex.Sqrt(new DoubleComplex(x1, y1));
                vals[i] = new QFloat64(dc.Re, dc.Im);
            }

            QFloat64NDimArray q = new QFloat64NDimArray(vals, qf.DimensionSize);
            List<IQLabValue> res = new List<IQLabValue>();
            res.Add(q);
            return res;



        }


        // radi isto sto i char, u sledecim verzijama ce biti uklonjena
        public List<IQLabValue> isstr(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> isstr \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> isstr \n Not enough input arguments."));

            return ischar(o);

        }
        
        public List<IQLabValue> deblank(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> deblank \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> deblank \n Not enough input arguments."));

            IQLabValueType en = o.ElementAt(0).GetEnumType();
            if ( en == IQLabValueType.QFloat64NDimArray)
            {
                //warning: Warning: Input should be a string. 
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(o.ElementAt(0));
                return res;
            }

            if (en == IQLabValueType.QCharNDimArray)
            {
                QCharNDimArray qc = new QCharNDimArray(o.ElementAt(0));

                //proverim da li je dvodimenzionalno
                if (qc.Dimension > 2)
                    throw (new NumericalCalculationsException("??? Error using ==> deblank \n Deblank only accepts up to two dimensions"));
            
                //pretvoricu ga u listu stringova
                List<string> ol = Helper.QCharNDimArrayToStringList(qc);
                List<string> nl = new List<string>();

                //naprabim novu listu kojoj sam uklonio beline sa kraja
                for (int i = 0; i < ol.Count; i++)
                    nl.Add(ol.ElementAt(i).Trim());

                // nju pretvorim u qchar ndim array
                QCharNDimArray nqc = Helper.StringListToQCharNDimArray(nl);

                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(nqc);
                return res;
            }

            if (en == IQLabValueType.QCell)
            {
               
                QCell c = (QCell)o.ElementAt(0);
                QCell nc = new QCell(c.Data, c.DimensionSize);
                //za svaki element
                for (int i = 0; i < c.Data.Count(); i++)
                {
                    //ukoliko je qchar deblankujemo inace nista ne radimo
                    IQLabValueType cen = nc.Data[i].GetEnumType();


                    if (cen == IQLabValueType.QCharNDimArray)
                    {
                        QCharNDimArray qc = new QCharNDimArray(nc.Data[i]);

                        //proverim da li je dvodimenzionalno
                        if (qc.Dimension > 2)
                            throw (new NumericalCalculationsException("??? Error using ==> deblank \n Deblank only accepts up to two dimensions"));

                        //pretvoricu ga u listu stringova
                        List<string> ol = Helper.QCharNDimArrayToStringList(qc);
                        List<string> nl = new List<string>();

                        //napravim novu listu kojoj sam uklonio beline sa kraja
                        for (int j = 0; j < ol.Count; i++)
                            nl.Add(ol.ElementAt(j).Trim());

                        // nju pretvorim u qchar ndim array
                        QCharNDimArray nqc = Helper.StringListToQCharNDimArray(nl);

                        nc.SetDataElement(i, nqc);
                    }

                }

                //tako promenjeni cell treba vratiti
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(nc);
                return res;
                
            }

            //inace treba da vrati exception 
            throw (new NumericalCalculationsException("??? Error using ==> deblank \n Input should be a string."));

        }


        //trazi jednodim ulaze
        // kada  se prosledi cell kaze da moze da radi samo za char vrednosti,
        // ali radi i za sve : qboolean, int64, uint64, double
        // ne pravi problem oko kompleksnih
        public List<IQLabValue> findstr(List<IQLabValue> o)
        {
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> findstr \n Too many input arguments."));

            if (o.Count < 2)
                throw (new NumericalCalculationsException("??? Error using ==> findstr \n Not enough input arguments."));


            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //konvertujem listu u float64
                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var oel in o)
                    of.Add(new QFloat64NDimArray(oel));

                //proverim da li je vektor
                foreach (var el in of)
                {
                    if (el.Dimension > 2)
                        throw (new NumericalCalculationsException("??? Error using ==> findstr \n Input strings must have one row."));

                    if (el.DimensionSize[0]!=1)
                        throw (new NumericalCalculationsException("??? Error using ==> findstr \n Input strings must have one row."));

                }

                //proverim koji je manje dimenzije
                int firstLength = of.ElementAt(0).DimensionSize[1];
                int secondLength = of.ElementAt(1).DimensionSize[1];

                QFloat64[] first;
                QFloat64[] second;

                // namestam tako da mi first bude kraci niz 
                if (firstLength <= secondLength)
                {
                    first = of.ElementAt(0).Data;
                    second = of.ElementAt(1).Data;
                }
                else
                {
                    first = of.ElementAt(1).Data;
                    second = of.ElementAt(0).Data;
                    int h = firstLength;
                    firstLength = secondLength;
                    secondLength = h;
                }

                int size = 0;
                List<QFloat64> vals = new List<QFloat64>();
                for (int i = 0; i <= secondLength - firstLength; i++)
                {
                    bool p = true;
                    for (int j = 0; j< firstLength; j++)
                        if ((first[j].Real != second[i + j].Real) || (first[j].Imag != second[i + j].Imag))
                        {
                            p = false;
                            break;
                        }
                    if (p)
                    {
                        vals.Add(new QFloat64(i + 1));
                        size++;
                    }
                }

                QFloat64NDimArray qf = new QFloat64NDimArray(vals.ToArray(), new int[]{ 1, size});
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(qf);
                return res;
            }
            else
            {
                throw (new NumericalCalculationsException("??? Error using ==> findstr \n Inputs must be character arrays."));
            }
        }

        
        //ukoliko je char ili cell radi nesto, inace vraca isto
        public List<IQLabValue> lower(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> lower \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> lower \n Not enough input arguments."));

            IQLabValueType en = o.ElementAt(0).GetEnumType();
            if (en == IQLabValueType.QCharNDimArray)
            {
                QCharNDimArray qc = new QCharNDimArray(o.ElementAt(0));
                QChar[] vals = new QChar[qc.Data.Count()];

                for (int i = 0; i < vals.Count(); i++)
                {
                    char c = qc.Data[i].Real;
                    if ((c >= 'A') && (c <= 'Z'))
                    
                        vals[i] = new QChar((char)('a' + c - 'A'));
                    else
                        vals[i] = new QChar(c);

                }
                QCharNDimArray q = new QCharNDimArray(vals, qc.DimensionSize);
                List<IQLabValue> res1 = new List<IQLabValue>();
                res1.Add(q);
                return res1;

            }
            if (en == IQLabValueType.QCell)
            {
                
                QCell c = (QCell)o.ElementAt(0);
                //pravimo duplikat posto ne smemo da menjamo argument
                QCell nc = new QCell(c.Data, c.DimensionSize);


                //za svaki element
                for (int i = 0; i < nc.Data.Count(); i++)
                {
                    //ukoliko je char, pretvorimo mala u velika inace nista ne radimo
                    IQLabValueType cen = nc.Data[i].GetEnumType();
                    if (cen == IQLabValueType.QCharNDimArray)
                    {
                        QCharNDimArray qc = new QCharNDimArray(nc.Data[i]);

                        QChar[] vals = new QChar[qc.Data.Count()];

                        for (int s = 0; s < vals.Count(); s++)
                        {
                            char l = qc.Data[s].Real;
                            if ((l >= 'A') && (l <= 'Z'))

                                vals[s] = new QChar((char)('a' + l - 'A'));
                            else
                                vals[s] = new QChar(l);

                        }

                        
                        QCharNDimArray nqc = new QCharNDimArray(vals, qc.DimensionSize); ;

                        nc.SetDataElement(i, nqc);
                    }

                }

                //tako promenjeni cell treba vratiti
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(nc);
                return res;
                
                
            }

            //inace
            List<IQLabValue> res2 = new List<IQLabValue>();
            res2.Add(o.ElementAt(0));
            return res2;
        }


        public List<IQLabValue> uper(List<IQLabValue> o)
        {
            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> uper \n Too many input arguments."));

            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> uper \n Not enough input arguments."));

            IQLabValueType en = o.ElementAt(0).GetEnumType();
            if (en == IQLabValueType.QCharNDimArray)
            {
                QCharNDimArray qc = new QCharNDimArray(o.ElementAt(0));
                QChar[] vals = new QChar[qc.Data.Count()];

                for (int i = 0; i < vals.Count(); i++)
                {
                    char c = qc.Data[i].Real;
                    if ((c >= 'a') && (c <= 'z'))

                        vals[i] = new QChar((char)('A' + c - 'a'));
                    else
                        vals[i] = new QChar(c);

                }
                QCharNDimArray q = new QCharNDimArray(vals, qc.DimensionSize);
                List<IQLabValue> res1 = new List<IQLabValue>();
                res1.Add(q);
                return res1;

            }
            if (en == IQLabValueType.QCell)
            {
               
                QCell c = (QCell)o.ElementAt(0);
                //pravimo duplikat posto ne smemo da menjamo argument
                QCell nc = new QCell(c.Data, c.DimensionSize);


                //za svaki element
                for (int i = 0; i < nc.Data.Count(); i++)
                {
                    //ukoliko je char, pretvorimo mala u velika inace nista ne radimo
                    IQLabValueType cen = nc.Data[i].GetEnumType();
                    if (cen == IQLabValueType.QCharNDimArray)
                    {
                        QCharNDimArray qc = new QCharNDimArray(nc.Data[i]);

                        QChar[] vals = new QChar[qc.Data.Count()];

                        for (int s = 0; s < vals.Count(); s++)
                        {
                            char l = qc.Data[s].Real;
                            if ((l >= 'a') && (l <= 'z'))

                                vals[s] = new QChar((char)('A' + l - 'a'));
                            else
                                vals[s] = new QChar(l);

                        }

                        
                        QCharNDimArray nqc = new QCharNDimArray(vals, qc.DimensionSize); ;

                        nc.SetDataElement(i, nqc);
                    }

                }

                //tako promenjeni cell treba vratiti
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(nc);
                return res;
                
                
            }

            //inace
            List<IQLabValue> res2 = new List<IQLabValue>();
            res2.Add(o.ElementAt(0));
            return res2;
        }

        //radi za sve
        // ja cu implementirati za stringove, ostalo u sledecoj verziji
        //treb
        public List<IQLabValue> strrep(List<IQLabValue> o)
        {
            if (o.Count > 3)
                throw (new NumericalCalculationsException("??? Error using ==> strrep \n Too many input arguments."));

            if (o.Count < 3)
                throw (new NumericalCalculationsException("??? Error using ==> strrep \n Not enough input arguments."));
            
           

            if (Helper.canConvertListToEnum(o, IQLabValueType.QCharNDimArray))
            {
                List<QCharNDimArray> qcl = new List<QCharNDimArray>();
                foreach (var el in o)
                    qcl.Add(new QCharNDimArray(el));

                //proverim da li su stringovi(jednoredni)
                foreach (var el in qcl)
                    if (Helper.IsString(el) == false)
                        throw (new NumericalCalculationsException("??? Error using ==> strrep \n Input strings must have one row."));

                //ok svi su stringovi, pretvoricu ih u liste(koje sce imati jedan element) i uzeti prvi
                string sourceString = Helper.QCharNDimArrayToStringList(qcl.ElementAt(0)).ElementAt(0);
                string oldString = Helper.QCharNDimArrayToStringList(qcl.ElementAt(1)).ElementAt(0);
                string newString = Helper.QCharNDimArrayToStringList(qcl.ElementAt(2)).ElementAt(0);

                //napravicu novu listu
                List<string> nl = new List<string>();
                nl.Add(sourceString.Replace(oldString, newString));

                //od te liste cu napraviti rezultujuci qcharndimarray
                QCharNDimArray nqc = Helper.StringListToQCharNDimArray(nl);

                //to cu vratiti
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(nqc);
                return res;

            }

            List<IQLabValue> newl = new List<IQLabValue>();
            newl.Add(o.ElementAt(1));
            newl.Add(o.ElementAt(2));
            IQLabValueType en = o.ElementAt(0).GetEnumType();

            //ako nam je zadat qcel, i zelimo da zamenimo pojavljivanje jednog u svakom charu
            if ((en == IQLabValueType.QCell) && (Helper.canConvertListToEnum(newl, IQLabValueType.QCharNDimArray)))
            {
                QCell c = (QCell)o.ElementAt(0);
                //iskopiram cell
                QCell nc = new QCell(c.Data, c.DimensionSize);

                //pokupim 
                string oldString = Helper.QCharNDimArrayToStringList(new QCharNDimArray(o.ElementAt(1))).ElementAt(0);
                string newString = Helper.QCharNDimArrayToStringList(new QCharNDimArray(o.ElementAt(2))).ElementAt(0);

                //proverim da li su stringovi
                if ((Helper.IsString(new QCharNDimArray(o.ElementAt(1)))== false)||(Helper.IsString(new QCharNDimArray(o.ElementAt(2)))== false))
                    throw (new NumericalCalculationsException("??? Error using ==> strrep \n Input strings must have one row."));

                for (int i = 0; i < nc.Data.Count(); i++)
                {
                    IQLabValueType cen = nc.Data[i].GetEnumType();
                    if (cen == IQLabValueType.QCharNDimArray)
                    {
                        QCharNDimArray qc = new QCharNDimArray(nc.Data[i]);

                        //proverim dali je string
                        if (Helper.IsString(qc) == false)
                            throw (new NumericalCalculationsException("??? Error using ==> strrep \n Input strings must have one row."));

                        string sourceString = Helper.QCharNDimArrayToStringList(qc).ElementAt(0);

                        //napravicu novu listu
                        List<string> nl = new List<string>();
                        nl.Add(sourceString.Replace(oldString, newString));

                        //od te liste cu napraviti rezultujuci qcharndimarray
                        QCharNDimArray nqc = Helper.StringListToQCharNDimArray(nl);

                        //postavicu taj element u nc
                        nc.SetDataElement(i, nqc);
                    }
                }

                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(nc);
                return res;



            }

            //inace
            throw (new NumericalCalculationsException("??? Error using ==> strrep \n Input strings must have one row."));

        }

        public List<IQLabValue> strcmp(List<IQLabValue> o)
        {
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> strcmp \n Too many input arguments."));

            if (o.Count < 2)
                throw (new NumericalCalculationsException("??? Error using ==> strcmp \n Not enough input arguments."));

            IQLabValueType fen = o.ElementAt(0).GetEnumType();
            IQLabValueType sen = o.ElementAt(1).GetEnumType();

            

            //ako su oba charovi
            if ((fen == IQLabValueType.QCharNDimArray) && (sen == IQLabValueType.QCharNDimArray))
            {
                QCharNDimArray fqc = new QCharNDimArray(o.ElementAt(0));
                QCharNDimArray sqc = new QCharNDimArray(o.ElementAt(1));

                bool p = Helper.AreQCharNDimArraysEaqual(fqc, sqc);

                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(p) }, new int[] { 1, 1 }));
                return res;
                
            }

            //ako je prvi char a drugi cell
            if ((fen == IQLabValueType.QCharNDimArray) && (sen == IQLabValueType.QCell))
            {
                QCharNDimArray fqc = new QCharNDimArray(o.ElementAt(0));
                QCell cc = new QCell(((QCell)o.ElementAt(1)).Data, ((QCell)o.ElementAt(1)).DimensionSize);

                QBooleanNDimArray qb = new QBooleanNDimArray(cc.DimensionSize);

                for (int i = 0; i < cc.Data.Count(); i++)
                {
                    IQLabValueType en = cc.Data[i].GetEnumType();
                    if (en == IQLabValueType.QCharNDimArray)
                    {
                        QCharNDimArray sqc = new QCharNDimArray(cc.Data[i]);
                        qb.SetDataElement(i, new QBoolean( Helper.AreQCharNDimArraysEaqual(fqc, sqc)));

                    }
                    else
                        qb.SetDataElement(i, new QBoolean(false));
                }

                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(qb);
                return res;
            }

            //ako su oba cellovi
            if ((fen == IQLabValueType.QCell) && (sen == IQLabValueType.QCell))
            {
                QCell fcc = new QCell(((QCell)o.ElementAt(0)).Data, ((QCell)o.ElementAt(0)).DimensionSize);
                QCell scc = new QCell(((QCell)o.ElementAt(1)).Data, ((QCell)o.ElementAt(1)).DimensionSize);

                //ako je prvi cell scalar
                if (Helper.checkIfCellIsScalar(o.ElementAt(0)))
                {
                    //pogledamo da li je njegov jedini element char, ako nije vracamo false
                    IQLabValueType elen = fcc[0, 0].GetEnumType();
                    if (elen != IQLabValueType.QCharNDimArray)
                    {
                        List<IQLabValue> res = new List<IQLabValue>();
                        res.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(false) }, new int[] { 1, 1 }));
                        return res;
                    }
                    else
                    {
                        QCharNDimArray fqc = new QCharNDimArray(fcc[0, 0]);
                        QBooleanNDimArray qb = new QBooleanNDimArray(scc.DimensionSize);

                        for (int i = 0; i < scc.Data.Count(); i++)
                        {
                            IQLabValueType en = scc.Data[i].GetEnumType();
                            if (en == IQLabValueType.QCharNDimArray)
                            {
                                QCharNDimArray sqc = new QCharNDimArray(scc.Data[i]);
                                qb.SetDataElement(i, new QBoolean(Helper.AreQCharNDimArraysEaqual(fqc, sqc)));

                            }
                            else
                                qb.SetDataElement(i, new QBoolean(false));
                        }

                        List<IQLabValue> res = new List<IQLabValue>();
                        res.Add(qb);
                        return res;
                    }


                 }

                //ako je drugi cell skalar
                if (Helper.checkIfCellIsScalar(o.ElementAt(1)))
                {
                    //pogledamo da li je njegov jedini element char, ako nije vracamo false
                    IQLabValueType elen = scc[0, 0].GetEnumType();
                    if (elen != IQLabValueType.QCharNDimArray)
                    {
                        List<IQLabValue> res = new List<IQLabValue>();
                        res.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(false) }, new int[] { 1, 1 }));
                        return res;
                    }
                    else
                    {
                        QCharNDimArray fqc = new QCharNDimArray(scc[0, 0]);
                        QBooleanNDimArray qb = new QBooleanNDimArray(fcc.DimensionSize);

                        for (int i = 0; i < fcc.Data.Count(); i++)
                        {
                            IQLabValueType en = fcc.Data[i].GetEnumType();
                            if (en == IQLabValueType.QCharNDimArray)
                            {
                                QCharNDimArray sqc = new QCharNDimArray(fcc.Data[i]);
                                qb.SetDataElement(i, new QBoolean(Helper.AreQCharNDimArraysEaqual(fqc, sqc)));

                            }
                            else
                                qb.SetDataElement(i, new QBoolean(false));
                        }

                        List<IQLabValue> res = new List<IQLabValue>();
                        res.Add(qb);
                        return res;
                    }

                }


                // ako oba nisu skalari, proverim da li su im dimenzije jednake
                if (Helper.checkDimensions(fcc, scc) == false)
                    throw (new NumericalCalculationsException("??? Error using ==> strcmp \n Inputs must be the same size or either one can be a scalar."));

                else
                {
                    QBooleanNDimArray qb = new QBooleanNDimArray(fcc.DimensionSize);
                    for (int i = 0; i < fcc.Data.Count(); i++)
                    {
                        IQLabValueType elen1 = fcc.Data[i].GetEnumType();
                        IQLabValueType elen2 = scc.Data[i].GetEnumType();
                        //ako je jedan od njih razlicit od chara, onda postavim false
                        if ((elen1 != IQLabValueType.QCharNDimArray) || (elen2 != IQLabValueType.QCharNDimArray))
                        {
                            qb.SetDataElement(i, new QBoolean(false));
                            continue;
                        }
                        //ako su oba char
                        QCharNDimArray fqc = new QCharNDimArray(fcc.Data[i]);
                        QCharNDimArray sqc = new QCharNDimArray(scc.Data[i]);
                        qb.SetDataElement(i, new QBoolean(Helper.AreQCharNDimArraysEaqual(fqc, sqc)));
                    }

                    List<IQLabValue> res = new List<IQLabValue>();
                    res.Add(qb);
                    return res;
                }



            }

            List<IQLabValue> res1 = new List<IQLabValue>();
            res1.Add(new QBooleanNDimArray(new QBoolean[]{new QBoolean(false)}, new int[]{1,1}));
            return res1;

        }

        //isto kao gornja funkcija, samo kad kreiram qcharndimarray onda ga pretvorim u lower 
        public List<IQLabValue> strcmpi(List<IQLabValue> o)
        {
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> strcmpi \n Too many input arguments."));

            if (o.Count < 2)
                throw (new NumericalCalculationsException("??? Error using ==> strcmpi \n Not enough input arguments."));

            IQLabValueType fen = o.ElementAt(0).GetEnumType();
            IQLabValueType sen = o.ElementAt(1).GetEnumType();



            //ako su oba charovi
            if ((fen == IQLabValueType.QCharNDimArray) && (sen == IQLabValueType.QCharNDimArray))
            {
                QCharNDimArray fqc = new QCharNDimArray(o.ElementAt(0));
                List<IQLabValue> args1 = new List<IQLabValue>();
                args1.Add(fqc);
                fqc = new QCharNDimArray(lower(args1).ElementAt(0));


                QCharNDimArray sqc = new QCharNDimArray(o.ElementAt(1));
                List<IQLabValue> args2 = new List<IQLabValue>();
                args2.Add(sqc);
                sqc = new QCharNDimArray(lower(args2).ElementAt(0));

               

                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(Helper.AreQCharNDimArraysEaqual(fqc, sqc)) }, new int[] { 1, 1 }));
                return res;

            }

            //ako je prvi char a drugi cell
            if ((fen == IQLabValueType.QCharNDimArray) && (sen == IQLabValueType.QCell))
            {
                QCharNDimArray fqc = new QCharNDimArray(o.ElementAt(0));

                List<IQLabValue> args1 = new List<IQLabValue>();
                args1.Add(fqc);
                fqc = new QCharNDimArray(lower(args1).ElementAt(0));

                QCell cc = new QCell(((QCell)o.ElementAt(1)).Data, ((QCell)o.ElementAt(1)).DimensionSize);

                QBooleanNDimArray qb = new QBooleanNDimArray(cc.DimensionSize);

                for (int i = 0; i < cc.Data.Count(); i++)
                {
                    IQLabValueType en = cc.Data[i].GetEnumType();
                    if (en == IQLabValueType.QCharNDimArray)
                    {
                        QCharNDimArray sqc = new QCharNDimArray(cc.Data[i]);
                        
                        List<IQLabValue> args2 = new List<IQLabValue>();
                        args2.Add(sqc);
                        sqc = new QCharNDimArray(lower(args2).ElementAt(0));

                        qb.SetDataElement(i, new QBoolean(Helper.AreQCharNDimArraysEaqual(fqc, sqc)));

                    }
                    else
                        qb.SetDataElement(i, new QBoolean(false));
                }

                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(qb);
                return res;
            }

            //ako su oba cellovi
            if ((fen == IQLabValueType.QCell) && (sen == IQLabValueType.QCell))
            {
                QCell fcc = new QCell(((QCell)o.ElementAt(0)).Data, ((QCell)o.ElementAt(0)).DimensionSize);
                QCell scc = new QCell(((QCell)o.ElementAt(1)).Data, ((QCell)o.ElementAt(1)).DimensionSize);

                //ako je prvi cell scalar
                if (Helper.checkIfCellIsScalar(o.ElementAt(0)))
                {
                    //pogledamo da li je njegov jedini element char, ako nije vracamo false
                    IQLabValueType elen = fcc[0, 0].GetEnumType();
                    if (elen != IQLabValueType.QCharNDimArray)
                    {
                        List<IQLabValue> res = new List<IQLabValue>();
                        res.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(false) }, new int[] { 1, 1 }));
                        return res;
                    }
                    else
                    {
                        QCharNDimArray fqc = new QCharNDimArray(fcc[0, 0]);
                        List<IQLabValue> args1 = new List<IQLabValue>();
                        args1.Add(fqc);
                        fqc = new QCharNDimArray(lower(args1).ElementAt(0));
                        QBooleanNDimArray qb = new QBooleanNDimArray(scc.DimensionSize);

                        for (int i = 0; i < scc.Data.Count(); i++)
                        {
                            IQLabValueType en = scc.Data[i].GetEnumType();
                            if (en == IQLabValueType.QCharNDimArray)
                            {
                                QCharNDimArray sqc = new QCharNDimArray(scc.Data[i]);
                                List<IQLabValue> args2 = new List<IQLabValue>();
                                args2.Add(sqc);
                                sqc = new QCharNDimArray(lower(args2).ElementAt(0));

                                qb.SetDataElement(i, new QBoolean(Helper.AreQCharNDimArraysEaqual(fqc, sqc)));

                            }
                            else
                                qb.SetDataElement(i, new QBoolean(false));
                        }

                        List<IQLabValue> res = new List<IQLabValue>();
                        res.Add(qb);
                        return res;
                    }


                }

                //ako je drugi cell skalar
                if (Helper.checkIfCellIsScalar(o.ElementAt(1)))
                {
                    //pogledamo da li je njegov jedini element char, ako nije vracamo false
                    IQLabValueType elen = scc[0, 0].GetEnumType();
                    if (elen != IQLabValueType.QCharNDimArray)
                    {
                        List<IQLabValue> res = new List<IQLabValue>();
                        res.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(false) }, new int[] { 1, 1 }));
                        return res;
                    }
                    else
                    {
                        QCharNDimArray fqc = new QCharNDimArray(scc[0, 0]);
                        List<IQLabValue> args1 = new List<IQLabValue>();
                        args1.Add(fqc);
                        fqc = new QCharNDimArray(lower(args1).ElementAt(0));

                        QBooleanNDimArray qb = new QBooleanNDimArray(fcc.DimensionSize);

                        for (int i = 0; i < fcc.Data.Count(); i++)
                        {
                            IQLabValueType en = fcc.Data[i].GetEnumType();
                            if (en == IQLabValueType.QCharNDimArray)
                            {
                                QCharNDimArray sqc = new QCharNDimArray(fcc.Data[i]);
                                List<IQLabValue> args2 = new List<IQLabValue>();
                                args2.Add(sqc);
                                sqc = new QCharNDimArray(lower(args2).ElementAt(0));
                                qb.SetDataElement(i, new QBoolean(Helper.AreQCharNDimArraysEaqual(fqc, sqc)));

                            }
                            else
                                qb.SetDataElement(i, new QBoolean(false));
                        }

                        List<IQLabValue> res = new List<IQLabValue>();
                        res.Add(qb);
                        return res;
                    }

                }


                // ako oba nisu skalari, proverim da li su im dimenzije jednake
                if (Helper.checkDimensions(fcc, scc) == false)
                    throw (new NumericalCalculationsException("??? Error using ==> strcmpi \n Inputs must be the same size or either one can be a scalar."));

                else
                {
                    QBooleanNDimArray qb = new QBooleanNDimArray(fcc.DimensionSize);
                    for (int i = 0; i < fcc.Data.Count(); i++)
                    {
                        IQLabValueType elen1 = fcc.Data[i].GetEnumType();
                        IQLabValueType elen2 = scc.Data[i].GetEnumType();
                        //ako je jedan od njih razlicit od chara, onda postavim false
                        if ((elen1 != IQLabValueType.QCharNDimArray) || (elen2 != IQLabValueType.QCharNDimArray))
                        {
                            qb.SetDataElement(i, new QBoolean(false));
                            continue;
                        }
                        //ako su oba char
                        QCharNDimArray fqc = new QCharNDimArray(fcc.Data[i]);
                        List<IQLabValue> args1 = new List<IQLabValue>();
                        args1.Add(fqc);
                        fqc = new QCharNDimArray(lower(args1).ElementAt(0));
                        QCharNDimArray sqc = new QCharNDimArray(scc.Data[i]);
                        List<IQLabValue> args2 = new List<IQLabValue>();
                        args2.Add(sqc);
                        sqc = new QCharNDimArray(lower(args2).ElementAt(0));
                        
                        qb.SetDataElement(i, new QBoolean(Helper.AreQCharNDimArraysEaqual(fqc, sqc)));
                    }

                    List<IQLabValue> res = new List<IQLabValue>();
                    res.Add(qb);
                    return res;
                }



            }

            List<IQLabValue> res1 = new List<IQLabValue>();
            res1.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(false) }, new int[] { 1, 1 }));
            return res1;

        }


        public List<IQLabValue> atan2(List<IQLabValue> o)
        {
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> atan2 \n Too many input arguments."));

            if (o.Count < 2)
                throw (new NumericalCalculationsException("??? Error using ==> atan2 \n Not enough input arguments."));



            foreach (var el in o)
            {
                IQLabValueType en = el.GetEnumType();
                if (en != IQLabValueType.QFloat64NDimArray)
                    throw (new NumericalCalculationsException("??? Undefined function or method 'atan2' for input arguments of type "+
                        Helper.PrintEnumName(en)+"."));
            }


            List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
            foreach (var oel in o)
                of.Add(new QFloat64NDimArray(oel));

            //ako je prvi scalar
            if (Helper.checkIfScalar(o.ElementAt(0)))
            {
                List<IQLabValue> res = new List<IQLabValue>();
                AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(1).Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = of.ElementAt(0).Data[0].Real;
                    double x2 = of.ElementAt(1).Data[i].Real;
                    
                    vals[i] = new AtomicTypes.QFloat64(Math.Atan2(x1,x2));
                }
                QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(1).DimensionSize);
                res.Add(qf);

                return res;
            }

            //ako je drugi scalar
            if (Helper.checkIfScalar(o.ElementAt(1)))
            {
                List<IQLabValue> res = new List<IQLabValue>();
                AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(0).Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = of.ElementAt(0).Data[i].Real;
                    double x2 = of.ElementAt(1).Data[0].Real;
                    
                    vals[i] = new AtomicTypes.QFloat64(Math.Atan2(x1,x2));
                }
                QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                res.Add(qf);

                return res;
            }

            //proverim da li su istih dimenzija
            if (Helper.checkDimensions(of.ElementAt(0), of.ElementAt(1)) == false)
                throw (new NumericalCalculationsException("Error using ==> atan2 \n Matrix dimensions must agree."));
            else
            //istih su dimenzija
            {
                List<IQLabValue> res = new List<IQLabValue>();
                AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(0).Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = of.ElementAt(0).Data[i].Real;
                    double x2 = of.ElementAt(1).Data[i].Real;
                    
                    vals[i] = new AtomicTypes.QFloat64(Math.Atan2(x1,x2));
                }
                QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                res.Add(qf);

                return res;
            }
            
        }


        public List<IQLabValue> hypot(List<IQLabValue> o)
        {
            if (o.Count > 2)
                throw (new NumericalCalculationsException("??? Error using ==> hypot \n Too many input arguments."));

            if (o.Count < 2)
                throw (new NumericalCalculationsException("??? Error using ==> hypot \n Not enough input arguments."));

            foreach (var el in o)
            {
                IQLabValueType en = el.GetEnumType();
                if (en != IQLabValueType.QFloat64NDimArray)
                    throw (new NumericalCalculationsException("??? Undefined function or method 'hypot' for input arguments of type " +
                        Helper.PrintEnumName(en) + "."));
            }


            List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
            foreach (var oel in o)
                of.Add(new QFloat64NDimArray(oel));

            //ako je prvi scalar
            if (Helper.checkIfScalar(o.ElementAt(0)))
            {
                List<IQLabValue> res = new List<IQLabValue>();
                AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(1).Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = of.ElementAt(0).Data[0].Real;
                    double x2 = of.ElementAt(1).Data[i].Real;
                    double y1 = of.ElementAt(0).Data[0].Imag;
                    double y2 = of.ElementAt(1).Data[i].Imag;

                    vals[i] = new AtomicTypes.QFloat64(Math.Sqrt(x1*x1+x2*x2+y1*y1+y2*y2));
                }
                QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(1).DimensionSize);
                res.Add(qf);

                return res;
            }

            //ako je drugi scalar
            if (Helper.checkIfScalar(o.ElementAt(1)))
            {
                List<IQLabValue> res = new List<IQLabValue>();
                AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(0).Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = of.ElementAt(0).Data[i].Real;
                    double x2 = of.ElementAt(1).Data[0].Real;
                    double y1 = of.ElementAt(0).Data[i].Imag;
                    double y2 = of.ElementAt(1).Data[0].Imag;

                    vals[i] = new AtomicTypes.QFloat64(Math.Sqrt(x1 * x1 + x2 * x2 + y1 * y1 + y2 * y2));
                }
                QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                res.Add(qf);

                return res;
            }

            //proverim da li su istih dimenzija
            if (Helper.checkDimensions(of.ElementAt(0), of.ElementAt(1)) == false)
                throw (new NumericalCalculationsException("Error using ==> hypot \n Matrix dimensions must agree."));
            else
            //istih su dimenzija
            {
                List<IQLabValue> res = new List<IQLabValue>();
                AtomicTypes.QFloat64[] vals = new AtomicTypes.QFloat64[of.ElementAt(0).Data.Count()];
                for (int i = 0; i < vals.Count(); i++)
                {
                    double x1 = of.ElementAt(0).Data[i].Real;
                    double x2 = of.ElementAt(1).Data[i].Real;
                    double y1 = of.ElementAt(0).Data[i].Imag;
                    double y2 = of.ElementAt(1).Data[i].Imag;


                    vals[i] = new AtomicTypes.QFloat64(Math.Sqrt(x1 * x1 + x2 * x2 + y1 * y1 + y2 * y2));
                }
                QFloat64NDimArray qf = new QFloat64NDimArray(vals, of.ElementAt(0).DimensionSize);
                res.Add(qf);

                return res;
            }

        }

        public List<IQLabValue> ffalse(List<IQLabValue> o)
        {
            if (o.Count == 0)
            {
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(false) }, new int[] { 1, 1 }));
                return res;
            }

            if (o.Count == 1)
            {
                IQLabValueType en = o.ElementAt(0).GetEnumType();
                HashSet<IQLabValueType> hs = new HashSet<IQLabValueType>();
                hs.Add(IQLabValueType.QInt64NDimArray);
                hs.Add(IQLabValueType.QUInt64NDimArray);
                hs.Add(IQLabValueType.QFloat64NDimArray);
                hs.Add(IQLabValueType.QBooleanNDimArray);

                if (hs.Contains(en) == false)
                    throw (new NumericalCalculationsException("??? Error using ==> false \n Inputs must be numeric."));

                if (Helper.isIQLabValueComplex(o.ElementAt(0)))
                    throw (new NumericalCalculationsException("??? Error using ==> false \n Size vector must be a row vector with real elements."));


                QFloat64NDimArray qf = new QFloat64NDimArray(o.ElementAt(0));
                if (qf.Dimension > 2)
                    throw (new NumericalCalculationsException("??? Error using ==> false \n Size vector must be a row vector with real elements."));

                if (qf.DimensionSize[0] != 1)
                    throw (new NumericalCalculationsException("??? Error using ==> false \n Size vector must be a row vector with real elements."));

                if (qf.DimensionSize[1] == 1)
                {
                    int c = (int)qf.Data[0].Real;
                    QBooleanNDimArray qb = new QBooleanNDimArray(new int[] { c, c });
                    for (int i = 0; i < qb.Data.Count(); i++)
                        qb.SetDataElement(i, new QBoolean(false));
                    List<IQLabValue> res = new List<IQLabValue>();
                    res.Add(new QBooleanNDimArray(qb));
                    return res;
                }

                int[] dsize = new int[qf.DimensionSize[1]];

                for (int i = 0; i < qf.Data.Count(); i++)
                    dsize[i] = (int)qf.Data[i].Real;

                QBooleanNDimArray qb1 = new QBooleanNDimArray(dsize);
                for (int i = 0; i < qb1.Data.Count(); i++)
                    qb1.SetDataElement(i, new QBoolean(false));
                List<IQLabValue> res1 = new List<IQLabValue>();
                res1.Add(new QBooleanNDimArray(qb1));
                return res1;


            }
            else
            {
                
                foreach (var el in o)
                {
                    IQLabValueType en = el.GetEnumType();
                    HashSet<IQLabValueType> hs = new HashSet<IQLabValueType>();
                    hs.Add(IQLabValueType.QInt64NDimArray);
                    hs.Add(IQLabValueType.QUInt64NDimArray);
                    hs.Add(IQLabValueType.QFloat64NDimArray);
                    hs.Add(IQLabValueType.QBooleanNDimArray);

                    if (hs.Contains(en) == false)
                        throw (new NumericalCalculationsException("??? Error using ==> false \n Inputs must be numeric."));

                    if (Helper.isIQLabValueComplex(el))
                        throw (new NumericalCalculationsException("??? Error using ==> false \n Size vector must be a row vector with real elements."));

                }


                //Warning: Input arguments must be scalar.
                int[] dsize = new int[o.Count];

                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var el in o)
                    of.Add(new QFloat64NDimArray(el));

                for (int i = 0; i < of.Count; i++)
                    dsize[i] = (int)of.ElementAt(i).Data[0].Real;

                QBooleanNDimArray qb = new QBooleanNDimArray(dsize);
                for (int i = 0; i < qb.Data.Count(); i++)
                    qb.SetDataElement(i, new QBoolean(false));
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(new QBooleanNDimArray(qb));
                return res;


            }


        }



        public List<IQLabValue> ttrue(List<IQLabValue> o)
        {
            if (o.Count == 0)
            {
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(new QBooleanNDimArray(new QBoolean[] { new QBoolean(true) }, new int[] { 1, 1 }));
                return res;
            }

            if (o.Count == 1)
            {
                IQLabValueType en = o.ElementAt(0).GetEnumType();
                HashSet<IQLabValueType> hs = new HashSet<IQLabValueType>();
                hs.Add(IQLabValueType.QInt64NDimArray);
                hs.Add(IQLabValueType.QUInt64NDimArray);
                hs.Add(IQLabValueType.QFloat64NDimArray);
                hs.Add(IQLabValueType.QBooleanNDimArray);

                if (hs.Contains(en) == false)
                    throw (new NumericalCalculationsException("??? Error using ==> true \n Inputs must be numeric."));

                if (Helper.isIQLabValueComplex(o.ElementAt(0)))
                    throw (new NumericalCalculationsException("??? Error using ==> true \n Size vector must be a row vector with real elements."));


                QFloat64NDimArray qf = new QFloat64NDimArray(o.ElementAt(0));
                if (qf.Dimension > 2)
                    throw (new NumericalCalculationsException("??? Error using ==> true \n Size vector must be a row vector with real elements."));

                if (qf.DimensionSize[0] != 1)
                    throw (new NumericalCalculationsException("??? Error using ==> true \n Size vector must be a row vector with real elements."));

                if (qf.DimensionSize[1] == 1)
                {
                    int c = (int)qf.Data[0].Real;
                    QBooleanNDimArray qb = new QBooleanNDimArray(new int[] { c, c });
                    for (int i = 0; i < qb.Data.Count(); i++)
                        qb.SetDataElement(i, new QBoolean(true));
                    List<IQLabValue> res = new List<IQLabValue>();
                    res.Add(new QBooleanNDimArray(qb));
                    return res;
                }

                int[] dsize = new int[qf.DimensionSize[1]];

                for (int i = 0; i < qf.Data.Count(); i++)
                    dsize[i] = (int)qf.Data[i].Real;

                QBooleanNDimArray qb1 = new QBooleanNDimArray(dsize);
                for (int i = 0; i < qb1.Data.Count(); i++)
                    qb1.SetDataElement(i, new QBoolean(true));
                List<IQLabValue> res1 = new List<IQLabValue>();
                res1.Add(new QBooleanNDimArray(qb1));
                return res1;


            }
            else
            {

                foreach (var el in o)
                {
                    IQLabValueType en = el.GetEnumType();
                    HashSet<IQLabValueType> hs = new HashSet<IQLabValueType>();
                    hs.Add(IQLabValueType.QInt64NDimArray);
                    hs.Add(IQLabValueType.QUInt64NDimArray);
                    hs.Add(IQLabValueType.QFloat64NDimArray);
                    hs.Add(IQLabValueType.QBooleanNDimArray);

                    if (hs.Contains(en) == false)
                        throw (new NumericalCalculationsException("??? Error using ==> true \n Inputs must be numeric."));

                    if (Helper.isIQLabValueComplex(el))
                        throw (new NumericalCalculationsException("??? Error using ==> true \n Size vector must be a row vector with real elements."));

                }


                //Warning: Input arguments must be scalar.
                int[] dsize = new int[o.Count];

                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var el in o)
                    of.Add(new QFloat64NDimArray(el));

                for (int i = 0; i < of.Count; i++)
                    dsize[i] = (int)of.ElementAt(i).Data[0].Real;

                QBooleanNDimArray qb = new QBooleanNDimArray(dsize);
                for (int i = 0; i < qb.Data.Count(); i++)
                    qb.SetDataElement(i, new QBoolean(true));
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(new QBooleanNDimArray(qb));
                return res;


            }


        }


        public List<IQLabValue> zeros(List<IQLabValue> o)
        {
            //zeros
            if (o.Count == 0)
            {
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(new QFloat64NDimArray(new QFloat64[] { new QFloat64(0) }, new int[] { 1, 1 }));
                return res;
            }

            if (o.Count == 1)
            {
                IQLabValueType en = o.ElementAt(0).GetEnumType();
                //zeros('int64')
                if (en == IQLabValueType.QCharNDimArray)
                {
                    QCharNDimArray qc = new QCharNDimArray(o.ElementAt(0));

                    if (qc.Dimension > 2)
                        throw (new NumericalCalculationsException("??? Error using ==> zeros \n Trailing string input must be a valid numeric class name."));

                    if (qc.DimensionSize[0] != 1)
                        throw (new NumericalCalculationsException("??? Error using ==> zeros \n Trailing string input must be a valid numeric class name."));

                    string cl = Helper.QCharNDimArrayToStringList(qc).ElementAt(0);

                    if (cl.CompareTo("int64") == 0)
                    {
                        List<IQLabValue> res = new List<IQLabValue>();
                        res.Add(new QInt64NDimArray(new QInt64[] { new QInt64(0) }, new int[] { 1, 1 }));
                        return res;
                    }
                    if (cl.CompareTo("uint64") == 0)
                    {
                        List<IQLabValue> res = new List<IQLabValue>();
                        res.Add(new QUInt64NDimArray(new QUInt64[] { new QUInt64(0) }, new int[] { 1, 1 }));
                        return res;
                    }

                    if (cl.CompareTo("double") == 0)
                    {
                        List<IQLabValue> res = new List<IQLabValue>();
                        res.Add(new QFloat64NDimArray(new QFloat64[] { new QFloat64(0) }, new int[] { 1, 1 }));
                        return res;
                    }

                    throw (new NumericalCalculationsException("??? Error using ==> zeros \n Trailing string input must be a valid numeric class name."));


                }

                if (Helper.canConvertToEnum(o.ElementAt(0), IQLabValueType.QFloat64NDimArray) == false)
                    throw (new NumericalCalculationsException("??? Error using ==> zeros \n Leading inputs must be numeric."));

                if (Helper.isIQLabValueComplex(o.ElementAt(0)))
                    throw (new NumericalCalculationsException("??? Error using ==> zeros \n Size vector must be a row vector with real elements."));


                QFloat64NDimArray qf = new QFloat64NDimArray(o.ElementAt(0));

                if (qf.Dimension > 2)
                    throw (new NumericalCalculationsException("??? Error using ==> zeros \n Size vector must be a row vector with real elements."));

                if (qf.DimensionSize[0] != 1)
                    throw (new NumericalCalculationsException("??? Error using ==> zeros \n Size vector must be a row vector with real elements."));

                //zeros(5)
                if (qf.DimensionSize[1] == 1)
                {
                    int c = (int)qf.Data[0].Real;
                    QFloat64NDimArray qf1 = new QFloat64NDimArray(new int[] { c, c });
                    for (int i = 0; i < qf1.Data.Count(); i++)
                        qf1.SetDataElement(i, new QFloat64(0));
                    List<IQLabValue> res = new List<IQLabValue>();
                    res.Add(qf1);
                    return res;
                }


                //zeros([1,2,3])
                int[] dsize = new int[qf.DimensionSize[1]];

                for (int i = 0; i < qf.Data.Count(); i++)
                    dsize[i] = (int)qf.Data[i].Real;

                QFloat64NDimArray qf2 = new QFloat64NDimArray(dsize);
                for (int i = 0; i < qf2.Data.Count(); i++)
                    qf2.SetDataElement(i, new QFloat64(0));
                List<IQLabValue> res1 = new List<IQLabValue>();
                res1.Add(qf2);
                return res1;


            }

            else
            {
                int argNum = o.Count;
                IQLabValueType en = o.ElementAt(argNum - 1).GetEnumType();
                if (en == IQLabValueType.QCharNDimArray)
                {
                    QCharNDimArray qc = new QCharNDimArray(o.ElementAt(argNum - 1));

                    if (qc.Dimension > 2)
                        throw (new NumericalCalculationsException("??? Error using ==> zeros \n Trailing string input must be a valid numeric class name."));

                    if (qc.DimensionSize[0] != 1)
                        throw (new NumericalCalculationsException("??? Error using ==> zeros \n Trailing string input must be a valid numeric class name."));

                    string cl = Helper.QCharNDimArrayToStringList(qc).ElementAt(0);

                    if (cl.CompareTo("int64") == 0)
                    {
                        if(Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray)==false)
                            throw (new NumericalCalculationsException("??? Error using ==> zeros \n Leading inputs must be numeric."));

                        foreach (var el in o)
                        {
                            if (Helper.isIQLabValueComplex(el))
                                throw (new NumericalCalculationsException("??? Error using ==> zeros \n Size vector must be a row vector with real elements."));

                        }

                        List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                        for (int i = 0; i < o.Count - 1; i++)
                            of.Add(new QFloat64NDimArray(o.ElementAt(i)));


                        if (argNum == 2)
                        {
                            QFloat64NDimArray qf = new QFloat64NDimArray(of.ElementAt(0));

                            if (qf.Dimension > 2)
                                throw (new NumericalCalculationsException("??? Error using ==> zeros \n Size vector must be a row vector with real elements."));

                            if (qf.DimensionSize[0] != 1)
                                throw (new NumericalCalculationsException("??? Error using ==> zeros \n Size vector must be a row vector with real elements."));
                            //zeros(5, 'int64')
                            if (qf.DimensionSize[1] == 1)
                            {
                                int c = (int)qf.Data[0].Real;
                                QInt64NDimArray qf1 = new QInt64NDimArray(new int[] { c, c });
                                for (int i = 0; i < qf1.Data.Count(); i++)
                                    qf1.SetDataElement(i, new QInt64(0));
                                List<IQLabValue> res = new List<IQLabValue>();
                                res.Add(qf1);
                                return res;
                            }

                            //zeros([1,2,3], 'int64')
                            int[] dsize = new int[qf.DimensionSize[1]];

                            for (int i = 0; i < qf.Data.Count(); i++)
                                dsize[i] = (int)qf.Data[i].Real;

                            QInt64NDimArray qf2 = new QInt64NDimArray(dsize);
                            for (int i = 0; i < qf2.Data.Count(); i++)
                                qf2.SetDataElement(i, new QInt64(0));
                            List<IQLabValue> res1 = new List<IQLabValue>();
                            res1.Add(qf2);
                            return res1;

                        }
                        else
                        //zeros(1,2,3,'int64')
                        {
                            int[] dsize = new int[of.Count];
                            //Warning: Input arguments must be scalar.
                            for (int i = 0; i < of.Count; i++)
                                dsize[i] = (int)of.ElementAt(i).Data[0].Real;

                            QInt64NDimArray qb = new QInt64NDimArray(dsize);
                            for (int i = 0; i < qb.Data.Count(); i++)
                                qb.SetDataElement(i, new QInt64(0));
                            List<IQLabValue> res = new List<IQLabValue>();
                            res.Add(qb);
                            return res;
                        }
                       
                    }
                    if (cl.CompareTo("uint64") == 0)
                    {
                        if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray)==false)
                            throw (new NumericalCalculationsException("??? Error using ==> zeros \n Leading inputs must be numeric."));

                        foreach (var el in o)
                        {
                            if (Helper.isIQLabValueComplex(el))
                                throw (new NumericalCalculationsException("??? Error using ==> zeros \n Size vector must be a row vector with real elements."));

                        }

                        List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                        for (int i = 0; i < o.Count - 1; i++)
                            of.Add(new QFloat64NDimArray(o.ElementAt(i)));


                        if (argNum == 2)
                        {
                            QFloat64NDimArray qf = new QFloat64NDimArray(of.ElementAt(0));

                            if (qf.Dimension > 2)
                                throw (new NumericalCalculationsException("??? Error using ==> zeros \n Size vector must be a row vector with real elements."));

                            if (qf.DimensionSize[0] != 1)
                                throw (new NumericalCalculationsException("??? Error using ==> zeros \n Size vector must be a row vector with real elements."));
                            //zeros(5, 'uint64')
                            if (qf.DimensionSize[1] == 1)
                            {
                                int c = (int)qf.Data[0].Real;
                                QUInt64NDimArray qf1 = new QUInt64NDimArray(new int[] { c, c });
                                for (int i = 0; i < qf1.Data.Count(); i++)
                                    qf1.SetDataElement(i, new QUInt64(0));
                                List<IQLabValue> res = new List<IQLabValue>();
                                res.Add(qf1);
                                return res;
                            }

                            //zeros([1,2,3], 'uint64')
                            int[] dsize = new int[qf.DimensionSize[1]];

                            for (int i = 0; i < qf.Data.Count(); i++)
                                dsize[i] = (int)qf.Data[i].Real;

                            QUInt64NDimArray qf2 = new QUInt64NDimArray(dsize);
                            for (int i = 0; i < qf2.Data.Count(); i++)
                                qf2.SetDataElement(i, new QUInt64(0));
                            List<IQLabValue> res1 = new List<IQLabValue>();
                            res1.Add(qf2);
                            return res1;

                        }
                        else
                        //zeros(1,2,3,'uint64')
                        {
                            int[] dsize = new int[of.Count];
                            //Warning: Input arguments must be scalar.
                            for (int i = 0; i < of.Count; i++)
                                dsize[i] = (int)of.ElementAt(i).Data[0].Real;

                            QUInt64NDimArray qb = new QUInt64NDimArray(dsize);
                            for (int i = 0; i < qb.Data.Count(); i++)
                                qb.SetDataElement(i, new QUInt64(0));
                            List<IQLabValue> res = new List<IQLabValue>();
                            res.Add(qb);
                            return res;
                        }
                        
                    }

                    if (cl.CompareTo("double") == 0)
                    {
                        if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray)==false)
                            throw (new NumericalCalculationsException("??? Error using ==> zeros \n Leading inputs must be numeric."));

                        foreach (var el in o)
                        {
                            if (Helper.isIQLabValueComplex(el))
                                throw (new NumericalCalculationsException("??? Error using ==> zeros \n Size vector must be a row vector with real elements."));

                        }

                        List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                        for (int i = 0; i < o.Count - 1; i++)
                            of.Add(new QFloat64NDimArray(o.ElementAt(i)));


                        if (argNum == 2)
                        {
                            QFloat64NDimArray qf = new QFloat64NDimArray(of.ElementAt(0));

                            if (qf.Dimension > 2)
                                throw (new NumericalCalculationsException("??? Error using ==> zeros \n Size vector must be a row vector with real elements."));

                            if (qf.DimensionSize[0] != 1)
                                throw (new NumericalCalculationsException("??? Error using ==> zeros \n Size vector must be a row vector with real elements."));
                            //zeros(5, 'double')
                            if (qf.DimensionSize[1] == 1)
                            {
                                int c = (int)qf.Data[0].Real;
                                QFloat64NDimArray qf1 = new QFloat64NDimArray(new int[] { c, c });
                                for (int i = 0; i < qf1.Data.Count(); i++)
                                    qf1.SetDataElement(i, new QFloat64(0));
                                List<IQLabValue> res = new List<IQLabValue>();
                                res.Add(qf1);
                                return res;
                            }

                            //zeros([1,2,3], 'double')
                            int[] dsize = new int[qf.DimensionSize[1]];

                            for (int i = 0; i < qf.Data.Count(); i++)
                                dsize[i] = (int)qf.Data[i].Real;

                            QFloat64NDimArray qf2 = new QFloat64NDimArray(dsize);
                            for (int i = 0; i < qf2.Data.Count(); i++)
                                qf2.SetDataElement(i, new QFloat64(0));
                            List<IQLabValue> res1 = new List<IQLabValue>();
                            res1.Add(qf2);
                            return res1;

                        }
                        else
                        //zeros(1,2,3,'double')
                        {
                            int[] dsize = new int[of.Count];
                            //Warning: Input arguments must be scalar.
                            for (int i = 0; i < of.Count; i++)
                                dsize[i] = (int)of.ElementAt(i).Data[0].Real;

                            QFloat64NDimArray qb = new QFloat64NDimArray(dsize);
                            for (int i = 0; i < qb.Data.Count(); i++)
                                qb.SetDataElement(i, new QFloat64(0));
                            List<IQLabValue> res = new List<IQLabValue>();
                            res.Add(qb);
                            return res;
                        }
                    }

                    throw (new NumericalCalculationsException("??? Error using ==> zeros \n Trailing string input must be a valid numeric class name."));


                
                }

                //zeros(1,2,3,4)
                //Warning: Input arguments must be scalar.
                int[] dsize1 = new int[o.Count];

                List<QFloat64NDimArray> of1 = new List<QFloat64NDimArray>();
                foreach (var el in o)
                    of1.Add(new QFloat64NDimArray(el));

                for (int i = 0; i < of1.Count; i++)
                    dsize1[i] = (int)of1.ElementAt(i).Data[0].Real;

                QFloat64NDimArray qb1 = new QFloat64NDimArray(dsize1);
                for (int i = 0; i < qb1.Data.Count(); i++)
                    qb1.SetDataElement(i, new QFloat64(0));
                List<IQLabValue> res2 = new List<IQLabValue>();
                res2.Add(qb1);
                return res2;

            }
        }



        public List<IQLabValue> ones(List<IQLabValue> o)
        {
            //ones
            if (o.Count == 0)
            {
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(new QFloat64NDimArray(new QFloat64[] { new QFloat64(1) }, new int[] { 1, 1 }));
                return res;
            }

            if (o.Count == 1)
            {
                IQLabValueType en = o.ElementAt(0).GetEnumType();
                //ones('int64')
                if (en == IQLabValueType.QCharNDimArray)
                {
                    QCharNDimArray qc = new QCharNDimArray(o.ElementAt(0));

                    if (qc.Dimension > 2)
                        throw (new NumericalCalculationsException("??? Error using ==> ones \n Trailing string input must be a valid numeric class name."));

                    if (qc.DimensionSize[0] != 1)
                        throw (new NumericalCalculationsException("??? Error using ==> ones \n Trailing string input must be a valid numeric class name."));

                    string cl = Helper.QCharNDimArrayToStringList(qc).ElementAt(0);

                    if (cl.CompareTo("int64") == 0)
                    {
                        List<IQLabValue> res = new List<IQLabValue>();
                        res.Add(new QInt64NDimArray(new QInt64[] { new QInt64(1) }, new int[] { 1, 1 }));
                        return res;
                    }
                    if (cl.CompareTo("uint64") == 0)
                    {
                        List<IQLabValue> res = new List<IQLabValue>();
                        res.Add(new QUInt64NDimArray(new QUInt64[] { new QUInt64(1) }, new int[] { 1, 1 }));
                        return res;
                    }

                    if (cl.CompareTo("double") == 0)
                    {
                        List<IQLabValue> res = new List<IQLabValue>();
                        res.Add(new QFloat64NDimArray(new QFloat64[] { new QFloat64(1) }, new int[] { 1, 1 }));
                        return res;
                    }

                    throw (new NumericalCalculationsException("??? Error using ==> ones \n Trailing string input must be a valid numeric class name."));


                }

                if (Helper.canConvertToEnum(o.ElementAt(0), IQLabValueType.QFloat64NDimArray) == false)
                    throw (new NumericalCalculationsException("??? Error using ==> ones \n Leading inputs must be numeric."));

                if (Helper.isIQLabValueComplex(o.ElementAt(0)))
                    throw (new NumericalCalculationsException("??? Error using ==> ones \n Size vector must be a row vector with real elements."));


                QFloat64NDimArray qf = new QFloat64NDimArray(o.ElementAt(0));

                if (qf.Dimension > 2)
                    throw (new NumericalCalculationsException("??? Error using ==> ones \n Size vector must be a row vector with real elements."));

                if (qf.DimensionSize[0] != 1)
                    throw (new NumericalCalculationsException("??? Error using ==> ones \n Size vector must be a row vector with real elements."));

                //ones(5)
                if (qf.DimensionSize[1] == 1)
                {
                    int c = (int)qf.Data[0].Real;
                    QFloat64NDimArray qf1 = new QFloat64NDimArray(new int[] { c, c });
                    for (int i = 0; i < qf1.Data.Count(); i++)
                        qf1.SetDataElement(i, new QFloat64(1));
                    List<IQLabValue> res = new List<IQLabValue>();
                    res.Add(qf1);
                    return res;
                }


                //ones([1,2,3])
                int[] dsize = new int[qf.DimensionSize[1]];

                for (int i = 0; i < qf.Data.Count(); i++)
                    dsize[i] = (int)qf.Data[i].Real;

                QFloat64NDimArray qf2 = new QFloat64NDimArray(dsize);
                for (int i = 0; i < qf2.Data.Count(); i++)
                    qf2.SetDataElement(i, new QFloat64(1));
                List<IQLabValue> res1 = new List<IQLabValue>();
                res1.Add(qf2);
                return res1;


            }

            else
            {
                int argNum = o.Count;
                IQLabValueType en = o.ElementAt(argNum - 1).GetEnumType();
                if (en == IQLabValueType.QCharNDimArray)
                {
                    QCharNDimArray qc = new QCharNDimArray(o.ElementAt(argNum - 1));

                    if (qc.Dimension > 2)
                        throw (new NumericalCalculationsException("??? Error using ==> ones \n Trailing string input must be a valid numeric class name."));

                    if (qc.DimensionSize[0] != 1)
                        throw (new NumericalCalculationsException("??? Error using ==> ones \n Trailing string input must be a valid numeric class name."));

                    string cl = Helper.QCharNDimArrayToStringList(qc).ElementAt(0);

                    if (cl.CompareTo("int64") == 0)
                    {
                        if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray) == false)
                            throw (new NumericalCalculationsException("??? Error using ==> ones \n Leading inputs must be numeric."));

                        foreach (var el in o)
                        {
                            if (Helper.isIQLabValueComplex(el))
                                throw (new NumericalCalculationsException("??? Error using ==> ones \n Size vector must be a row vector with real elements."));

                        }

                        List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                        for (int i = 0; i < o.Count - 1; i++)
                            of.Add(new QFloat64NDimArray(o.ElementAt(i)));


                        if (argNum == 2)
                        {
                            QFloat64NDimArray qf = new QFloat64NDimArray(of.ElementAt(0));

                            if (qf.Dimension > 2)
                                throw (new NumericalCalculationsException("??? Error using ==> ones \n Size vector must be a row vector with real elements."));

                            if (qf.DimensionSize[0] != 1)
                                throw (new NumericalCalculationsException("??? Error using ==> ones \n Size vector must be a row vector with real elements."));
                            //ones(5, 'int64')
                            if (qf.DimensionSize[1] == 1)
                            {
                                int c = (int)qf.Data[0].Real;
                                QInt64NDimArray qf1 = new QInt64NDimArray(new int[] { c, c });
                                for (int i = 0; i < qf1.Data.Count(); i++)
                                    qf1.SetDataElement(i, new QInt64(1));
                                List<IQLabValue> res = new List<IQLabValue>();
                                res.Add(qf1);
                                return res;
                            }

                            //ones([1,2,3], 'int64')
                            int[] dsize = new int[qf.DimensionSize[1]];

                            for (int i = 0; i < qf.Data.Count(); i++)
                                dsize[i] = (int)qf.Data[i].Real;

                            QInt64NDimArray qf2 = new QInt64NDimArray(dsize);
                            for (int i = 0; i < qf2.Data.Count(); i++)
                                qf2.SetDataElement(i, new QInt64(1));
                            List<IQLabValue> res1 = new List<IQLabValue>();
                            res1.Add(qf2);
                            return res1;

                        }
                        else
                        //zeros(1,2,3,'int64')
                        {
                            int[] dsize = new int[of.Count];
                            //Warning: Input arguments must be scalar.
                            for (int i = 0; i < of.Count; i++)
                                dsize[i] = (int)of.ElementAt(i).Data[0].Real;

                            QInt64NDimArray qb = new QInt64NDimArray(dsize);
                            for (int i = 0; i < qb.Data.Count(); i++)
                                qb.SetDataElement(i, new QInt64(1));
                            List<IQLabValue> res = new List<IQLabValue>();
                            res.Add(qb);
                            return res;
                        }

                    }
                    if (cl.CompareTo("uint64") == 0)
                    {
                        if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray) == false)
                            throw (new NumericalCalculationsException("??? Error using ==> ones \n Leading inputs must be numeric."));

                        foreach (var el in o)
                        {
                            if (Helper.isIQLabValueComplex(el))
                                throw (new NumericalCalculationsException("??? Error using ==> ones \n Size vector must be a row vector with real elements."));

                        }

                        List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                        for (int i = 0; i < o.Count - 1; i++)
                            of.Add(new QFloat64NDimArray(o.ElementAt(i)));


                        if (argNum == 2)
                        {
                            QFloat64NDimArray qf = new QFloat64NDimArray(of.ElementAt(0));

                            if (qf.Dimension > 2)
                                throw (new NumericalCalculationsException("??? Error using ==> ones \n Size vector must be a row vector with real elements."));

                            if (qf.DimensionSize[0] != 1)
                                throw (new NumericalCalculationsException("??? Error using ==> ones \n Size vector must be a row vector with real elements."));
                            //zeros(5, 'uint64')
                            if (qf.DimensionSize[1] == 1)
                            {
                                int c = (int)qf.Data[0].Real;
                                QUInt64NDimArray qf1 = new QUInt64NDimArray(new int[] { c, c });
                                for (int i = 0; i < qf1.Data.Count(); i++)
                                    qf1.SetDataElement(i, new QUInt64(1));
                                List<IQLabValue> res = new List<IQLabValue>();
                                res.Add(qf1);
                                return res;
                            }

                            //ones([1,2,3], 'uint64')
                            int[] dsize = new int[qf.DimensionSize[1]];

                            for (int i = 0; i < qf.Data.Count(); i++)
                                dsize[i] = (int)qf.Data[i].Real;

                            QUInt64NDimArray qf2 = new QUInt64NDimArray(dsize);
                            for (int i = 0; i < qf2.Data.Count(); i++)
                                qf2.SetDataElement(i, new QUInt64(1));
                            List<IQLabValue> res1 = new List<IQLabValue>();
                            res1.Add(qf2);
                            return res1;

                        }
                        else
                        //ones(1,2,3,'uint64')
                        {
                            int[] dsize = new int[of.Count];
                            //Warning: Input arguments must be scalar.
                            for (int i = 0; i < of.Count; i++)
                                dsize[i] = (int)of.ElementAt(i).Data[0].Real;

                            QUInt64NDimArray qb = new QUInt64NDimArray(dsize);
                            for (int i = 0; i < qb.Data.Count(); i++)
                                qb.SetDataElement(i, new QUInt64(1));
                            List<IQLabValue> res = new List<IQLabValue>();
                            res.Add(qb);
                            return res;
                        }

                    }

                    if (cl.CompareTo("double") == 0)
                    {
                        if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray) == false)
                            throw (new NumericalCalculationsException("??? Error using ==> ones \n Leading inputs must be numeric."));

                        foreach (var el in o)
                        {
                            if (Helper.isIQLabValueComplex(el))
                                throw (new NumericalCalculationsException("??? Error using ==> ones \n Size vector must be a row vector with real elements."));

                        }

                        List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                        for (int i = 0; i < o.Count - 1; i++)
                            of.Add(new QFloat64NDimArray(o.ElementAt(i)));


                        if (argNum == 2)
                        {
                            QFloat64NDimArray qf = new QFloat64NDimArray(of.ElementAt(0));

                            if (qf.Dimension > 2)
                                throw (new NumericalCalculationsException("??? Error using ==> ones \n Size vector must be a row vector with real elements."));

                            if (qf.DimensionSize[0] != 1)
                                throw (new NumericalCalculationsException("??? Error using ==> ones \n Size vector must be a row vector with real elements."));
                            //zeros(5, 'double')
                            if (qf.DimensionSize[1] == 1)
                            {
                                int c = (int)qf.Data[0].Real;
                                QFloat64NDimArray qf1 = new QFloat64NDimArray(new int[] { c, c });
                                for (int i = 0; i < qf1.Data.Count(); i++)
                                    qf1.SetDataElement(i, new QFloat64(1));
                                List<IQLabValue> res = new List<IQLabValue>();
                                res.Add(qf1);
                                return res;
                            }

                            //zeros([1,2,3], 'double')
                            int[] dsize = new int[qf.DimensionSize[1]];

                            for (int i = 0; i < qf.Data.Count(); i++)
                                dsize[i] = (int)qf.Data[i].Real;

                            QFloat64NDimArray qf2 = new QFloat64NDimArray(dsize);
                            for (int i = 0; i < qf2.Data.Count(); i++)
                                qf2.SetDataElement(i, new QFloat64(1));
                            List<IQLabValue> res1 = new List<IQLabValue>();
                            res1.Add(qf2);
                            return res1;

                        }
                        else
                        //ones(1,2,3,'double')
                        {
                            int[] dsize = new int[of.Count];
                            //Warning: Input arguments must be scalar.
                            for (int i = 0; i < of.Count; i++)
                                dsize[i] = (int)of.ElementAt(i).Data[0].Real;

                            QFloat64NDimArray qb = new QFloat64NDimArray(dsize);
                            for (int i = 0; i < qb.Data.Count(); i++)
                                qb.SetDataElement(i, new QFloat64(1));
                            List<IQLabValue> res = new List<IQLabValue>();
                            res.Add(qb);
                            return res;
                        }
                    }

                    throw (new NumericalCalculationsException("??? Error using ==> ones \n Trailing string input must be a valid numeric class name."));



                }

                //zeros(1,2,3,4)
                //Warning: Input arguments must be scalar.
                int[] dsize1 = new int[o.Count];

                List<QFloat64NDimArray> of1 = new List<QFloat64NDimArray>();
                foreach (var el in o)
                    of1.Add(new QFloat64NDimArray(el));

                for (int i = 0; i < of1.Count; i++)
                    dsize1[i] = (int)of1.ElementAt(i).Data[0].Real;

                QFloat64NDimArray qb1 = new QFloat64NDimArray(dsize1);
                for (int i = 0; i < qb1.Data.Count(); i++)
                    qb1.SetDataElement(i, new QFloat64(1));
                List<IQLabValue> res2 = new List<IQLabValue>();
                res2.Add(qb1);
                return res2;

            }
        }



        public List<IQLabValue> eye(List<IQLabValue> o)
        {
            
            if (o.Count == 0)
            {
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(new QFloat64NDimArray(new QFloat64[] { new QFloat64(1) }, new int[] { 1, 1 }));
                return res;
            }

            

            if (o.Count == 1)
            {
                IQLabValueType en = o.ElementAt(0).GetEnumType();
                //eye('int64')
                if (en == IQLabValueType.QCharNDimArray)
                {
                    QCharNDimArray qc = new QCharNDimArray(o.ElementAt(0));

                    if (qc.Dimension > 2)
                        throw (new NumericalCalculationsException("??? Error using ==> eye Only input must be numeric or a valid numeric class name."));

                    if (qc.DimensionSize[0] != 1)
                        throw (new NumericalCalculationsException("??? Error using ==> eye Only input must be numeric or a valid numeric class name."));

                    string cl = Helper.QCharNDimArrayToStringList(qc).ElementAt(0);

                    if (cl.CompareTo("int64") == 0)
                    {
                        List<IQLabValue> res = new List<IQLabValue>();
                        res.Add(new QInt64NDimArray(new QInt64[] { new QInt64(1) }, new int[] { 1, 1 }));
                        return res;
                    }
                    if (cl.CompareTo("uint64") == 0)
                    {
                        List<IQLabValue> res = new List<IQLabValue>();
                        res.Add(new QUInt64NDimArray(new QUInt64[] { new QUInt64(1) }, new int[] { 1, 1 }));
                        return res;
                    }

                    if (cl.CompareTo("double") == 0)
                    {
                        List<IQLabValue> res = new List<IQLabValue>();
                        res.Add(new QFloat64NDimArray(new QFloat64[] { new QFloat64(1) }, new int[] { 1, 1 }));
                        return res;
                    }

                    throw (new NumericalCalculationsException("??? Error using ==> eye Only input must be numeric or a valid numeric class name."));


                }

                if (Helper.canConvertToEnum(o.ElementAt(0), IQLabValueType.QFloat64NDimArray) == false)
                    throw (new NumericalCalculationsException("??? Error using ==> eye Only input must be numeric or a valid numeric class name."));

                if (Helper.isIQLabValueComplex(o.ElementAt(0)))
                    throw (new NumericalCalculationsException("??? Error using ==> eye \n Size vector must be a row vector with real elements."));


                QFloat64NDimArray qf = new QFloat64NDimArray(o.ElementAt(0));

                if (qf.Dimension > 2)
                    throw (new NumericalCalculationsException("??? Error using ==> eye \n Size vector must be a row vector with real elements."));

                if (qf.DimensionSize[0] != 1)
                    throw (new NumericalCalculationsException("??? Error using ==> eye \n Size vector must be a row vector with real elements."));

                //eye(5)
                if (qf.DimensionSize[1] == 1)
                {
                    int c = (int)qf.Data[0].Real;
                    QFloat64NDimArray qf1 = new QFloat64NDimArray(new int[] { c, c });
                    for (int i = 0; i < qf1.Data.Count(); i++)
                        qf1.SetDataElement(i, new QFloat64(0));

                    for (int i = 0; i < c; i++)
                        for (int j = 0; j < c; j++)
                            if (i == j)
                                qf1[i, j] = new QFloat64(1);

                    List<IQLabValue> res = new List<IQLabValue>();
                    res.Add(qf1);
                    return res;
                }


                //eye([1,2,3])
                if (qf.DimensionSize[1] > 2)
                    throw (new NumericalCalculationsException("??? Error using ==> eye \n Unknown command option."));

                int[] dsize = new int[2];

                dsize[0] = (int)qf.Data[0].Real;
                dsize[1] = (int)qf.Data[1].Real;

                QFloat64NDimArray qf2 = new QFloat64NDimArray(dsize);
                for (int i = 0; i < qf2.Data.Count(); i++)
                    qf2.SetDataElement(i, new QFloat64(0));


                for (int i = 0; i < dsize[0]; i++)
                    for (int j = 0; j < dsize[1]; j++)
                        if (i == j)
                            qf2[i, j] = new QFloat64(1);

                List<IQLabValue> res1 = new List<IQLabValue>();
                res1.Add(qf2);
                return res1;


            }


            
            if (o.Count == 2)
            {
                IQLabValueType en = o.ElementAt(1).GetEnumType();
                if (en == IQLabValueType.QCharNDimArray)
                {
                    QCharNDimArray qc = new QCharNDimArray(o.ElementAt(1));

                    if (qc.Dimension > 2)
                        throw (new NumericalCalculationsException("??? Error using ==> eye Only input must be numeric or a valid numeric class name."));

                    if (qc.DimensionSize[0] != 1)
                        throw (new NumericalCalculationsException("??? Error using ==> eye Only input must be numeric or a valid numeric class name."));

                    string cl = Helper.QCharNDimArrayToStringList(qc).ElementAt(0);

                    if (cl.CompareTo("int64") == 0)
                    {
                        if (Helper.canConvertToEnum(o.ElementAt(0), IQLabValueType.QFloat64NDimArray) == false)
                            throw (new NumericalCalculationsException("??? Error using ==> eye \n Leading inputs must be numeric."));

                        QFloat64NDimArray qf = new QFloat64NDimArray(o.ElementAt(0));

                        if (qf.Dimension > 2)
                            throw (new NumericalCalculationsException("??? Error using ==> eye \n Size vector must be a row vector with real elements."));

                        if (qf.DimensionSize[0] != 1)
                            throw (new NumericalCalculationsException("??? Error using ==> eye \n Size vector must be a row vector with real elements."));

                        //eye(5, 'int64')
                        if (qf.DimensionSize[1] == 1)
                        {
                            int c = (int)qf.Data[0].Real;
                            QInt64NDimArray qf1 = new QInt64NDimArray(new int[] { c, c });
                            for (int i = 0; i < qf1.Data.Count(); i++)
                                qf1.SetDataElement(i, new QInt64(0));

                            for (int i = 0; i < c; i++)
                                for (int j = 0; j < c; j++)
                                    if (i == j)
                                        qf1[i, j] = new QInt64(1);

                            List<IQLabValue> res = new List<IQLabValue>();
                            res.Add(qf1);
                            return res;
                        }

                        //eye([1,2,3], 'int64')
                        if (qf.DimensionSize[1] > 2)
                            throw (new NumericalCalculationsException("??? Error using ==> eye \n Unknown command option."));

                        int[] dsize = new int[2];

                        dsize[0] = (int)qf.Data[0].Real;
                        dsize[1] = (int)qf.Data[1].Real;

                        QInt64NDimArray qf2 = new QInt64NDimArray(dsize);
                        for (int i = 0; i < qf2.Data.Count(); i++)
                            qf2.SetDataElement(i, new QInt64(0));


                        for (int i = 0; i < dsize[0]; i++)
                            for (int j = 0; j < dsize[1]; j++)
                                if (i == j)
                                    qf2[i, j] = new QInt64(1);

                        List<IQLabValue> res1 = new List<IQLabValue>();
                        res1.Add(qf2);
                        return res1;
                    }
                    if (cl.CompareTo("uint64") == 0)
                    {
                        if (Helper.canConvertToEnum(o.ElementAt(0), IQLabValueType.QFloat64NDimArray) == false)
                            throw (new NumericalCalculationsException("??? Error using ==> eye \n Leading inputs must be numeric."));

                        QFloat64NDimArray qf = new QFloat64NDimArray(o.ElementAt(0));

                        if (qf.Dimension > 2)
                            throw (new NumericalCalculationsException("??? Error using ==> eye \n Size vector must be a row vector with real elements."));

                        if (qf.DimensionSize[0] != 1)
                            throw (new NumericalCalculationsException("??? Error using ==> eye \n Size vector must be a row vector with real elements."));

                        //eye(5, 'uint64')
                        if (qf.DimensionSize[1] == 1)
                        {
                            int c = (int)qf.Data[0].Real;
                            QUInt64NDimArray qf1 = new QUInt64NDimArray(new int[] { c, c });
                            for (int i = 0; i < qf1.Data.Count(); i++)
                                qf1.SetDataElement(i, new QUInt64(0));

                            for (int i = 0; i < c; i++)
                                for (int j = 0; j < c; j++)
                                    if (i == j)
                                        qf1[i, j] = new QUInt64(1);

                            List<IQLabValue> res = new List<IQLabValue>();
                            res.Add(qf1);
                            return res;
                        }

                        //eye([1,2,3], 'uint64')
                        if (qf.DimensionSize[1] > 2)
                            throw (new NumericalCalculationsException("??? Error using ==> eye \n Unknown command option."));

                        int[] dsize = new int[2];

                        dsize[0] = (int)qf.Data[0].Real;
                        dsize[1] = (int)qf.Data[1].Real;

                        QUInt64NDimArray qf2 = new QUInt64NDimArray(dsize);
                        for (int i = 0; i < qf2.Data.Count(); i++)
                            qf2.SetDataElement(i, new QUInt64(0));


                        for (int i = 0; i < dsize[0]; i++)
                            for (int j = 0; j < dsize[1]; j++)
                                if (i == j)
                                    qf2[i, j] = new QUInt64(1);

                        List<IQLabValue> res1 = new List<IQLabValue>();
                        res1.Add(qf2);
                        return res1;
                    }

                    if (cl.CompareTo("double") == 0)
                    {
                        if (Helper.canConvertToEnum(o.ElementAt(0), IQLabValueType.QFloat64NDimArray) == false)
                            throw (new NumericalCalculationsException("??? Error using ==> eye \n Leading inputs must be numeric."));

                        QFloat64NDimArray qf = new QFloat64NDimArray(o.ElementAt(0));

                        if (qf.Dimension > 2)
                            throw (new NumericalCalculationsException("??? Error using ==> eye \n Size vector must be a row vector with real elements."));

                        if (qf.DimensionSize[0] != 1)
                            throw (new NumericalCalculationsException("??? Error using ==> eye \n Size vector must be a row vector with real elements."));

                        //eye(5, 'double')
                        if (qf.DimensionSize[1] == 1)
                        {
                            int c = (int)qf.Data[0].Real;
                            QFloat64NDimArray qf1 = new QFloat64NDimArray(new int[] { c, c });
                            for (int i = 0; i < qf1.Data.Count(); i++)
                                qf1.SetDataElement(i, new QFloat64(0));

                            for (int i = 0; i < c; i++)
                                for (int j = 0; j < c; j++)
                                    if (i == j)
                                        qf1[i, j] = new QFloat64(1);

                            List<IQLabValue> res = new List<IQLabValue>();
                            res.Add(qf1);
                            return res;
                        }

                        //eye([1,2,3], 'double')
                        if (qf.DimensionSize[1] > 2)
                            throw (new NumericalCalculationsException("??? Error using ==> eye \n Unknown command option."));

                        int[] dsize = new int[2];

                        dsize[0] = (int)qf.Data[0].Real;
                        dsize[1] = (int)qf.Data[1].Real;

                        QFloat64NDimArray qf2 = new QFloat64NDimArray(dsize);
                        for (int i = 0; i < qf2.Data.Count(); i++)
                            qf2.SetDataElement(i, new QFloat64(0));


                        for (int i = 0; i < dsize[0]; i++)
                            for (int j = 0; j < dsize[1]; j++)
                                if (i == j)
                                    qf2[i, j] = new QFloat64(1);

                        List<IQLabValue> res1 = new List<IQLabValue>();
                        res1.Add(qf2);
                        return res1;
                    }

                    throw (new NumericalCalculationsException("??? Error using ==> eye Only input must be numeric or a valid numeric class name."));


                }

                //eye(5,6)
                //Warning: Input arguments must be scalar. 
                if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray) == false)
                            throw (new NumericalCalculationsException("??? Error using ==> eye \n Leading inputs must be numeric."));

                List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                foreach (var el in o)
                    of.Add(new QFloat64NDimArray(el));

                int[] dsize1 = new int[2];

                dsize1[0] = (int)of.ElementAt(0).Data[0].Real;
                dsize1[1] = (int)of.ElementAt(1).Data[0].Real;

                QFloat64NDimArray qf3 = new QFloat64NDimArray(dsize1);
                for (int i = 0; i < qf3.Data.Count(); i++)
                    qf3.SetDataElement(i, new QFloat64(0));


                for (int i = 0; i < dsize1[0]; i++)
                    for (int j = 0; j < dsize1[1]; j++)
                        if (i == j)
                            qf3[i, j] = new QFloat64(1);

                List<IQLabValue> res2 = new List<IQLabValue>();
                res2.Add(qf3);
                return res2;


            }

            

            if (o.Count == 3)
            {
                IQLabValueType en = o.ElementAt(2).GetEnumType();
                if (en != IQLabValueType.QCharNDimArray)
                    throw (new NumericalCalculationsException("??? Error using ==> eye \n Third input must be a valid numeric class name."));

                else
                {

                    QCharNDimArray qc = new QCharNDimArray(o.ElementAt(2));

                    if (qc.Dimension > 2)
                        throw (new NumericalCalculationsException("??? Error using ==> eye \n Trailing string input must be a valid numeric class name."));

                    if (qc.DimensionSize[0] != 1)
                        throw (new NumericalCalculationsException("??? Error using ==> eye \n Trailing string input must be a valid numeric class name."));

                    string cl = Helper.QCharNDimArrayToStringList(qc).ElementAt(0);

                    if (cl.CompareTo("int64") == 0)
                    {
                        if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray) == false)
                            throw (new NumericalCalculationsException("??? Error using ==> eye \n Leading inputs must be numeric."));

                        List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                        
                        of.Add(new QFloat64NDimArray(o.ElementAt(0)));
                        of.Add(new QFloat64NDimArray(o.ElementAt(1)));

                        int[] dsize1 = new int[2];

                        dsize1[0] = (int)of.ElementAt(0).Data[0].Real;
                        dsize1[1] = (int)of.ElementAt(1).Data[0].Real;

                        QInt64NDimArray qf3 = new QInt64NDimArray(dsize1);
                        for (int i = 0; i < qf3.Data.Count(); i++)
                            qf3.SetDataElement(i, new QInt64(0));


                        for (int i = 0; i < dsize1[0]; i++)
                            for (int j = 0; j < dsize1[1]; j++)
                                if (i == j)
                                    qf3[i, j] = new QInt64(1);

                        List<IQLabValue> res2 = new List<IQLabValue>();
                        res2.Add(qf3);
                        return res2;
                    }

                    if (cl.CompareTo("uint64") == 0)
                    {
                        if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray) == false)
                            throw (new NumericalCalculationsException("??? Error using ==> eye \n Leading inputs must be numeric."));

                        List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();
                        
                        of.Add(new QFloat64NDimArray(o.ElementAt(0)));
                        of.Add(new QFloat64NDimArray(o.ElementAt(1)));

                        int[] dsize1 = new int[2];

                        dsize1[0] = (int)of.ElementAt(0).Data[0].Real;
                        dsize1[1] = (int)of.ElementAt(1).Data[0].Real;

                        QUInt64NDimArray qf3 = new QUInt64NDimArray(dsize1);
                        for (int i = 0; i < qf3.Data.Count(); i++)
                            qf3.SetDataElement(i, new QUInt64(0));


                        for (int i = 0; i < dsize1[0]; i++)
                            for (int j = 0; j < dsize1[1]; j++)
                                if (i == j)
                                    qf3[i, j] = new QUInt64(1);

                        List<IQLabValue> res2 = new List<IQLabValue>();
                        res2.Add(qf3);
                        return res2;
                       
                    }

                    if (cl.CompareTo("double") == 0)
                    {
                        if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray) == false)
                            throw (new NumericalCalculationsException("??? Error using ==> eye \n Leading inputs must be numeric."));

                        List<QFloat64NDimArray> of = new List<QFloat64NDimArray>();

                        of.Add(new QFloat64NDimArray(o.ElementAt(0)));
                        of.Add(new QFloat64NDimArray(o.ElementAt(1)));

                        int[] dsize1 = new int[2];

                        dsize1[0] = (int)of.ElementAt(0).Data[0].Real;
                        dsize1[1] = (int)of.ElementAt(1).Data[0].Real;

                        QFloat64NDimArray qf3 = new QFloat64NDimArray(dsize1);
                        for (int i = 0; i < qf3.Data.Count(); i++)
                            qf3.SetDataElement(i, new QFloat64(0));


                        for (int i = 0; i < dsize1[0]; i++)
                            for (int j = 0; j < dsize1[1]; j++)
                                if (i == j)
                                    qf3[i, j] = new QFloat64(1);

                        List<IQLabValue> res2 = new List<IQLabValue>();
                        res2.Add(qf3);
                        return res2;
                        
                    }

                    throw (new NumericalCalculationsException("??? Error using ==> eye \n Trailing string input must be a valid numeric class name."));


                }

            }

            

            
            if (o.Count > 3)
                throw (new NumericalCalculationsException("??? Error using ==> eye \n Too many input arguments."));

           

            return null;
        }






        public List<IQLabValue> logical(List<IQLabValue> o)
        {
            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> logical \n Not enough input arguments."));

            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> logical \n Too many input arguments."));

            IQLabValueType en = o.ElementAt(0).GetEnumType();

            List<IQLabValue> res = new List<IQLabValue>();

            switch(en)
            {
                case IQLabValueType.QBooleanNDimArray:
                    res.Add(o.ElementAt(0));
                    break;

                case IQLabValueType.QCharNDimArray:
                    throw (new NumericalCalculationsException("??? Error using ==> logical \n Unsupported conversion from char to logical."));
                
                case IQLabValueType.QInt64NDimArray:
                    
                    if (Helper.isIQLabValueComplex(o.ElementAt(0))) 
                        throw (new NumericalCalculationsException("??? Error using ==> logical \n Complex values cannot be converted to logicals."));

                    QInt64NDimArray qia = (QInt64NDimArray)o.ElementAt(0);

                    QBooleanNDimArray qba = new QBooleanNDimArray(qia.DimensionSize);
                    Counter c = new Counter(qia.DimensionSize);
                    for (c.reset(); !c.isAtEnd(); c.plusPlus())
                    {
                        int[] a = c.getCurrent();
                        qba[a] = new QBoolean(qia[a]);
                    }
                    res.Add(qba);
                    break;
                
                case IQLabValueType.QUInt64NDimArray:

                    if (Helper.isIQLabValueComplex(o.ElementAt(0)))
                        throw (new NumericalCalculationsException("??? Error using ==> logical \n Complex values cannot be converted to logicals."));

                    QUInt64NDimArray quia = (QUInt64NDimArray)o.ElementAt(0);
                    QBooleanNDimArray qba1 = new QBooleanNDimArray(quia.DimensionSize);
                    Counter c1 = new Counter(quia.DimensionSize);
                    for (c1.reset(); !c1.isAtEnd(); c1.plusPlus())
                    {
                        int[] a = c1.getCurrent();
                        qba1[a] = new QBoolean(quia[a]);
                    }
                    res.Add(qba1);
                    break;
                
                case IQLabValueType.QFloat64NDimArray:

                    if (Helper.isIQLabValueComplex(o.ElementAt(0)))
                        throw (new NumericalCalculationsException("??? Error using ==> logical \n Complex values cannot be converted to logicals."));

                    QFloat64NDimArray qfa = (QFloat64NDimArray)o.ElementAt(0);
                    QBooleanNDimArray qba2 = new QBooleanNDimArray(qfa.DimensionSize);
                    Counter c2 = new Counter(qfa.DimensionSize);
                    for (c2.reset(); !c2.isAtEnd(); c2.plusPlus())
                    {
                        int[] a = c2.getCurrent();
                        qba2[a] = new QBoolean(qfa[a]);
                    }
                    res.Add(qba2);
                    break;
                
                default:
                    throw (new NumericalCalculationsException("??? Error using ==> logical \n Conversion to logical from "+Helper.PrintEnumName(en)+" is not possible."));
            
            }

            return res;

        }

        public List<IQLabValue> cchar(List<IQLabValue> o)
        {
            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> char \n Not enough input arguments."));

            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> char \n Too many input arguments."));

            IQLabValueType en = o.ElementAt(0).GetEnumType();

            List<IQLabValue> res = new List<IQLabValue>();

            switch (en)
            {
                case IQLabValueType.QCharNDimArray:
                    res.Add(o.ElementAt(0));
                    break;

                case IQLabValueType.QBooleanNDimArray:
                    throw (new NumericalCalculationsException("??? Error using ==> char \n Conversion to char from logical is not possible."));

                case IQLabValueType.QInt64NDimArray:

                    if (Helper.isIQLabValueComplex(o.ElementAt(0)))
                        throw (new NumericalCalculationsException("??? Error using ==> logical \n Complex values cannot be converted to chars."));

                    QInt64NDimArray qia = (QInt64NDimArray)o.ElementAt(0);

                    QCharNDimArray qca = new QCharNDimArray(qia.DimensionSize);
                    Counter c = new Counter(qia.DimensionSize);
                    for (c.reset(); !c.isAtEnd(); c.plusPlus())
                    {
                        int[] a = c.getCurrent();
                        qca[a] = new QChar(qia[a]);
                    }
                    res.Add(qca);
                    break;

                case IQLabValueType.QUInt64NDimArray:

                    if (Helper.isIQLabValueComplex(o.ElementAt(0)))
                        throw (new NumericalCalculationsException("??? Error using ==> logical \n Complex values cannot be converted to chars."));

                    QUInt64NDimArray quia = (QUInt64NDimArray)o.ElementAt(0);
                    QCharNDimArray qca1 = new QCharNDimArray(quia.DimensionSize);
                    Counter c1 = new Counter(quia.DimensionSize);
                    for (c1.reset(); !c1.isAtEnd(); c1.plusPlus())
                    {
                        int[] a = c1.getCurrent();
                        qca1[a] = new QChar(quia[a]);
                    }
                    res.Add(qca1);
                    break;

                case IQLabValueType.QFloat64NDimArray:

                    if (Helper.isIQLabValueComplex(o.ElementAt(0)))
                        throw (new NumericalCalculationsException("??? Error using ==> logical \n Complex values cannot be converted to chars."));

                    QFloat64NDimArray qfa = (QFloat64NDimArray)o.ElementAt(0);
                    QCharNDimArray qca2 = new QCharNDimArray(qfa.DimensionSize);
                    Counter c2 = new Counter(qfa.DimensionSize);
                    for (c2.reset(); !c2.isAtEnd(); c2.plusPlus())
                    {
                        int[] a = c2.getCurrent();
                        qca2[a] = new QChar(qfa[a]);
                    }
                    res.Add(qca2);
                    break;

                default:
                    throw (new NumericalCalculationsException("??? Error using ==> char \n Conversion to char from " + Helper.PrintEnumName(en) + " is not possible."));

            }

            return res;

        }

        public List<IQLabValue> int64(List<IQLabValue> o)
        {
            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> int64 \n Not enough input arguments."));

            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> int64 \n Too many input arguments."));

            IQLabValueType en = o.ElementAt(0).GetEnumType();

            List<IQLabValue> res = new List<IQLabValue>();

            switch (en)
            {
                case IQLabValueType.QBooleanNDimArray:
                    QBooleanNDimArray qba = (QBooleanNDimArray)o.ElementAt(0);
                    QInt64NDimArray qia = new QInt64NDimArray(qba.DimensionSize);
                    Counter c = new Counter(qba.DimensionSize);
                    for (c.reset(); !c.isAtEnd(); c.plusPlus())
                    {
                        int[] a = c.getCurrent();
                        qia[a] = new QInt64(qba[a]);
                    }
                    res.Add(qia);
                    break;

                case IQLabValueType.QCharNDimArray:
                    QCharNDimArray qca = (QCharNDimArray)o.ElementAt(0);
                    QInt64NDimArray qia1 = new QInt64NDimArray(qca.DimensionSize);
                    Counter c1 = new Counter(qca.DimensionSize);
                    for (c1.reset(); !c1.isAtEnd(); c1.plusPlus())
                    {
                        int[] a = c1.getCurrent();
                        qia1[a] = new QInt64(qca[a]);
                    }
                    res.Add(qia1);
                    break;

                case IQLabValueType.QInt64NDimArray:
                    res.Add(o.ElementAt(0));
                    break;

                case IQLabValueType.QUInt64NDimArray:

                    QUInt64NDimArray quia = (QUInt64NDimArray)o.ElementAt(0);
                    QInt64NDimArray qia2 = new QInt64NDimArray(quia.DimensionSize);
                    Counter c2 = new Counter(quia.DimensionSize);
                    for (c2.reset(); !c2.isAtEnd(); c2.plusPlus())
                    {
                        int[] a = c2.getCurrent();
                        qia2[a] = new QInt64(quia[a]);
                    }
                    res.Add(qia2);
                    break;

                case IQLabValueType.QFloat64NDimArray:
                    QFloat64NDimArray qfa = (QFloat64NDimArray)o.ElementAt(0);
                    QInt64NDimArray qia3 = new QInt64NDimArray(qfa.DimensionSize);
                    Counter c3 = new Counter(qfa.DimensionSize);
                    for (c3.reset(); !c3.isAtEnd(); c3.plusPlus())
                    {
                        int[] a = c3.getCurrent();
                        qia3[a] = new QInt64(qfa[a]);
                    }
                    res.Add(qia3);
                    break;

                default:
                    throw (new NumericalCalculationsException("??? Error using ==> int64 \n Conversion to int64 from " + Helper.PrintEnumName(en) + " is not possible."));

            }

            return res;

        }


        public List<IQLabValue> uint64(List<IQLabValue> o)
        {
            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> uint64 \n Not enough input arguments."));

            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> uint64 \n Too many input arguments."));

            IQLabValueType en = o.ElementAt(0).GetEnumType();

            List<IQLabValue> res = new List<IQLabValue>();

            switch (en)
            {
                case IQLabValueType.QBooleanNDimArray:
                    QBooleanNDimArray qba = (QBooleanNDimArray)o.ElementAt(0);
                    QUInt64NDimArray quia = new QUInt64NDimArray(qba.DimensionSize);
                    Counter c = new Counter(qba.DimensionSize);
                    for (c.reset(); !c.isAtEnd(); c.plusPlus())
                    {
                        int[] a = c.getCurrent();
                        quia[a] = new QUInt64(qba[a]);
                    }
                    res.Add(quia);
                    break;

                case IQLabValueType.QCharNDimArray:
                    QCharNDimArray qca = (QCharNDimArray)o.ElementAt(0);
                    QUInt64NDimArray quia1 = new QUInt64NDimArray(qca.DimensionSize);
                    Counter c1 = new Counter(qca.DimensionSize);
                    for (c1.reset(); !c1.isAtEnd(); c1.plusPlus())
                    {
                        int[] a = c1.getCurrent();
                        quia1[a] = new QUInt64(qca[a]);
                    }
                    res.Add(quia1);
                    break;

                case IQLabValueType.QInt64NDimArray:
                    
                    QInt64NDimArray qia = (QInt64NDimArray)o.ElementAt(0);
                    QUInt64NDimArray quia2 = new QUInt64NDimArray(qia.DimensionSize);
                    Counter c2 = new Counter(qia.DimensionSize);
                    for (c2.reset(); !c2.isAtEnd(); c2.plusPlus())
                    {
                        int[] a = c2.getCurrent();
                        quia2[a] = new QUInt64(qia[a]);
                    }
                    res.Add(quia2);
                    break;


                case IQLabValueType.QUInt64NDimArray:
                    res.Add(o.ElementAt(0));
                    break;

                    
                case IQLabValueType.QFloat64NDimArray:
                    QFloat64NDimArray qfa = (QFloat64NDimArray)o.ElementAt(0);
                    QUInt64NDimArray quia3 = new QUInt64NDimArray(qfa.DimensionSize);
                    Counter c3 = new Counter(qfa.DimensionSize);
                    for (c3.reset(); !c3.isAtEnd(); c3.plusPlus())
                    {
                        int[] a = c3.getCurrent();
                        quia3[a] = new QUInt64(qfa[a]);
                    }
                    res.Add(quia3);
                    break;

                default:
                    throw (new NumericalCalculationsException("??? Error using ==> uint64 \n Conversion to uint64 from " + Helper.PrintEnumName(en) + " is not possible."));

            }

            return res;

        }

        public List<IQLabValue> ddouble(List<IQLabValue> o)
        {
            if (o.Count < 1)
                throw (new NumericalCalculationsException("??? Error using ==> double \n Not enough input arguments."));

            if (o.Count > 1)
                throw (new NumericalCalculationsException("??? Error using ==> double \n Too many input arguments."));

            if (Helper.canConvertToEnum(o.ElementAt(0), IQLabValueType.QFloat64NDimArray))
            {
                QFloat64NDimArray qfa = new QFloat64NDimArray(o.ElementAt(0));
                List<IQLabValue> res = new List<IQLabValue>();
                res.Add(qfa);
                return res;
            }
            else
            {
                throw (new NumericalCalculationsException("??? Error using ==> double \n Conversion to double from " +
                    Helper.PrintEnumName(o.ElementAt(0).GetEnumType()) + " is not possible."));
            }
        
        
        
        }


        #endregion



        #region Nakrpljene-Treba dorada

        //nakrpljena, treba da se promeni tako da radi za sve slucajeve
        public List<IQLabValue> min(List<IQLabValue> o)
        {
            if (o.Count() != 1)
                throw (new NumericalCalculationsException("Not implemented yet. Please report."));

            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //konvertujem u float64
                QFloat64NDimArray element = new QFloat64NDimArray(o.ElementAt(0));

                int[] size = element.DimensionSize;
                //proverim da li je 2dim 
                if (size.Length > 2)
                {
                    throw (new NumericalCalculationsException("Not implemented yet. Please report."));
                }
                else
                {
                    //proverim da li je vektor - dimenzije 1,n
                    if (size[0] == 1)
                    {
                        QFloat64 min = element[0, 0];
                        for (int i = 1; i < size[1]; i++)
                        {
                            QFloat64 curr = element[0, i];
                            if (curr.Real < min.Real)
                                min = new QFloat64(curr.Real, curr.Imag);
                            if (curr.Real == min.Real)
                                if (curr.Imag < min.Imag)
                                    min = new QFloat64(curr.Real, curr.Imag);

                        }

                        List<IQLabValue> res = new List<IQLabValue>();
                        res.Add(new QFloat64NDimArray(new QFloat64[] { min }, new int[] { 1, 1 }));
                        return res;
                    }
                    else //dvodimenzionalna matrica
                    {
                        QFloat64NDimArray res = new QFloat64NDimArray(new int[] { 1, size[1] });
                        for (int j = 0; j < size[1]; j++)
                        {
                            res[0, j] = element[0, j];
                            for (int i = 1; i < size[0]; i++)
                            {
                                QFloat64 curr = element[i, j];
                                if (curr.Real < res[0, j].Real)
                                    res[0, j] = new QFloat64(curr.Real, curr.Imag);
                                if (curr.Real == res[0, j].Real)
                                    if (curr.Imag < res[0, j].Imag)
                                        res[0, j] = new QFloat64(curr.Real, curr.Imag);
                            }
                        }

                        List<IQLabValue> resList = new List<IQLabValue>();
                        resList.Add(res);
                        return resList;
                    }
                }


            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'min' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }


        }


        //nakrpljena, treba da se promeni tako da radi za sve slucajeve
        public List<IQLabValue> max(List<IQLabValue> o)
        {
            if (o.Count() != 1)
                throw (new NumericalCalculationsException("Not implemented yet. Please report."));

            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //konvertujem u float64
                QFloat64NDimArray element = new QFloat64NDimArray(o.ElementAt(0));

                int[] size = element.DimensionSize;
                //proverim da li je 2dim 
                if (size.Length > 2)
                {
                    throw (new NumericalCalculationsException("Not implemented yet. Please report."));
                }
                else
                {
                    //proverim da li je vektor - dimenzije 1,n
                    if (size[0] == 1)
                    {
                        QFloat64 max = element[0, 0];
                        for (int i = 1; i < size[1]; i++)
                        {
                            QFloat64 curr = element[0, i];
                            if (curr.Real > max.Real)
                                max = new QFloat64(curr.Real, curr.Imag);
                            if (curr.Real == max.Real)
                                if (curr.Imag > max.Imag)
                                    max = new QFloat64(curr.Real, curr.Imag);

                        }

                        List<IQLabValue> res = new List<IQLabValue>();
                        res.Add(new QFloat64NDimArray(new QFloat64[] { max }, new int[] { 1, 1 }));
                        return res;
                    }
                    else //dvodimenzionalna matrica
                    {
                        QFloat64NDimArray res = new QFloat64NDimArray(new int[] { 1, size[1] });
                        for (int j = 0; j < size[1]; j++)
                        {
                            res[0, j] = element[0, j];
                            for (int i = 1; i < size[0]; i++)
                            {
                                QFloat64 curr = element[i, j];
                                if (curr.Real > res[0, j].Real)
                                    res[0, j] = new QFloat64(curr.Real, curr.Imag);
                                if (curr.Real == res[0, j].Real)
                                    if (curr.Imag > res[0, j].Imag)
                                        res[0, j] = new QFloat64(curr.Real, curr.Imag);
                            }
                        }

                        List<IQLabValue> resList = new List<IQLabValue>();
                        resList.Add(res);
                        return resList;
                    }
                }


            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'max' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }


        }


        //nakrpljena, treba da se promeni tako da radi za sve slucajeve
        //NAPOMENA: funkcija nije definisana za int64 i uint64, 
        public List<IQLabValue> sum(List<IQLabValue> o)
        {
            if (o.Count() != 1)
                throw (new NumericalCalculationsException("Not implemented yet. Please report."));

            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //konvertujem u float64
                QFloat64NDimArray element = new QFloat64NDimArray(o.ElementAt(0));

                int[] size = element.DimensionSize;
                //proverim da li je 2dim 
                if (size.Length > 2)
                {
                    throw (new NumericalCalculationsException("Not implemented yet. Please report."));
                }
                else
                {
                    //proverim da li je vektor - dimenzije 1,n
                    if (size[0] == 1)
                    {
                        QFloat64 sum = element[0, 0];
                        for (int i = 1; i < size[1]; i++)
                        {
                            QFloat64 curr = element[0, i];
                            sum =  new QFloat64(curr.Real + sum.Real, curr.Imag + sum.Imag);

                        }

                        List<IQLabValue> res = new List<IQLabValue>();
                        res.Add(new QFloat64NDimArray(new QFloat64[] { sum }, new int[] { 1, 1 }));
                        return res;
                    }
                    else //dvodimenzionalna matrica
                    {
                        QFloat64NDimArray res = new QFloat64NDimArray(new int[] { 1, size[1] });
                        for (int j = 0; j < size[1]; j++)
                        {
                            res[0, j] = element[0, j];
                            for (int i = 1; i < size[0]; i++)
                            {
                                QFloat64 curr = element[i, j];
                                res[0, j] = new QFloat64(curr.Real + res[0,j].Real, curr.Imag + res[0,j].Imag);
                            }
                        }

                        List<IQLabValue> resList = new List<IQLabValue>();
                        resList.Add(res);
                        return resList;
                    }
                }


            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'sum' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }


        }


        //nakrpljena, treba da se promeni tako da radi za sve slucajeve
        //NAPOMENA: funkcija nije definisana za int64 i uint64, 
        public List<IQLabValue> prod(List<IQLabValue> o)
        {
            if (o.Count() != 1)
                throw (new NumericalCalculationsException("Not implemented yet. Please report."));

            if (Helper.canConvertListToEnum(o, IQLabValueType.QFloat64NDimArray))
            {
                //konvertujem u float64
                QFloat64NDimArray element = new QFloat64NDimArray(o.ElementAt(0));

                int[] size = element.DimensionSize;
                //proverim da li je 2dim 
                if (size.Length > 2)
                {
                    throw (new NumericalCalculationsException("Not implemented yet. Please report."));
                }
                else
                {
                    //proverim da li je vektor - dimenzije 1,n
                    if (size[0] == 1)
                    {
                        QFloat64 prod = element[0, 0];
                        DoubleComplex dc = new DoubleComplex(prod.Real, prod.Imag);
                        for (int i = 1; i < size[1]; i++)
                        {
                            QFloat64 curr = element[0, i];
                            DoubleComplex currdc = new DoubleComplex(curr.Real, curr.Imag);
                            dc = dc * currdc;

                        }

                        List<IQLabValue> res = new List<IQLabValue>();
                        res.Add(new QFloat64NDimArray(new QFloat64[] { new QFloat64(dc.Re,dc.Im) }, new int[] { 1, 1 }));
                        return res;
                    }
                    else //dvodimenzionalna matrica
                    {
                        QFloat64NDimArray res = new QFloat64NDimArray(new int[] { 1, size[1] });
                        for (int j = 0; j < size[1]; j++)
                        {
                            
                            DoubleComplex dc = new DoubleComplex(element[0, j].Real, element[0, j].Imag);
                            for (int i = 1; i < size[0]; i++)
                            {
                                QFloat64 curr = element[i, j];
                                DoubleComplex dccurr = new DoubleComplex(curr.Real, curr.Imag);
                                dc = dc * dccurr;
                            }
                            res[0, j] = new QFloat64(dc.Re, dc.Im);
                        }

                        List<IQLabValue> resList = new List<IQLabValue>();
                        resList.Add(res);
                        return resList;
                    }
                }


            }
            else
            // nije uspelo konvertovanje, treba da ispise da ne moze da uzme te argumente
            {
                throw (new NumericalCalculationsException("??? Undefined function or method 'prod' for input arguments of type " +
                    Helper.PrintEnumName(Helper.TypeOfThatCouldNotConvert(o, IQLabValueType.QFloat64NDimArray)) + "."));
            }


        }

        //nakrpljena
        //ova fja je iskomentarisana jer je nova dodata u fajlu Functions_MS.cs!!!
       /* public List<IQLabValue> size(List<IQLabValue> o)
        {
            // NAPOMENA NETKO UBACIO OVO DA NA MISHITJE PRORADI :)
            if (o.Count == 2)
            {
                List<IQLabValue> temp = new List<IQLabValue>();
                temp.Add(new QFloat64NDimArray(new QFloat64[1]{ new QFloat64(((QFloat64NDimArray)o[0]).DimensionSize[0]) }, new int[2]{ 1, 1}));
                return temp;
            }
            
            if (o.Count != 1)
                throw (new NumericalCalculationsException("Not implemented yet. Please report."));

            IQLabValueType en = o.ElementAt(0).GetEnumType();

            switch (en)
            {
                case IQLabValueType.QBooleanNDimArray:
                case IQLabValueType.QCharNDimArray:
                case IQLabValueType.QInt64NDimArray:
                case IQLabValueType.QUInt64NDimArray:
                case IQLabValueType.QFloat64NDimArray:
                    QFloat64NDimArray qfa = new QFloat64NDimArray(o.ElementAt(0));
                    QFloat64NDimArray res = new QFloat64NDimArray(new int[]{1, qfa.Dimension});

                    for (int i = 0; i < qfa.Dimension; i++)
                    {
                        res[0, i] = new QFloat64(qfa.DimensionSize[i]);
                    }

                    List<IQLabValue> listRes = new List<IQLabValue>();
                    listRes.Add(res);
                    return listRes;
                    
                    
                case IQLabValueType.QCell:
                    QCell qc = (QCell)o.ElementAt(0);
                    QFloat64NDimArray res1 = new QFloat64NDimArray(new int[] { 1, qc.Dimension });

                    for (int i = 0; i < qc.Dimension; i++)
                    {
                        res1[0, i] = new QFloat64(qc.DimensionSize[i]);
                    }

                    List<IQLabValue> listRes1 = new List<IQLabValue>();
                    listRes1.Add(res1);
                    return listRes1;
                default:
                    throw (new NumericalCalculationsException("Not implemented yet. Please report."));
                    
            }
        }*/

        

        #endregion

    }
}